标签:des style http color io os 使用 ar java
2 5 1 1 4 2 1 3 3 7 2 1.5 5 4.5 3.5 1.25 7.5 4 6 3 10 7 3 0 0 1 1 1 0 2 1 2 0 3 1
7.63 0.00
——————————————————————分割线————————————
题目大意:
给你n个矩形,求这些矩形相交超过两次的面积和
思路:
原来的面积并是覆盖一次,而这题要求两次以上,自己刚开始并没有区分一次覆盖和两次覆盖的区别!!!
面积并和周长并是区间内或运算!!!
cnt[]表示覆盖次数
对于某个节点:
1:cnt[]>=2表示被完全覆盖,那么长度就等于区间长度
2:叶子节点为0
3:cnt[]==1表示被完全覆盖,但是它的左右子区间如果存在覆盖一次以上的,那么加上这次的,就正好两次以上了,所以要由左右子树的覆盖一次以上的长度得到
4:cnt[]==0 不是表示没有被覆盖,而是没有被完全覆盖,那么要取得覆盖两次以上的,就等于左右子树覆盖两次以上的长度得到
好好理解区间或运算!!!
注意点:
离散化:排序+去重 unique去重函数,返回最后一个元素的迭代器
点化线段——右端点-1
计算长度——线段变回点 右端点+1
写完这个,就去搞体积交3次以上的题目:hdu3642 Get The Treasury
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn=2222; using namespace std; int cnt[maxn<<2]; double sum1[maxn<<2],sum2[maxn<<2]; double X[maxn+10]; struct Seg { double l,r,h; int s; Seg() {}; Seg(double a,double b,double c,double d):l(a),r(b),h(c),s(d) {}; bool operator<(const Seg&cmp)const { return h<cmp.h; } }; Seg ss[maxn+10]; void push_up1(int rt,int l,int r) { if(cnt[rt]) sum1[rt]=X[r+1]-X[l]; else if(l==r) sum1[rt]=0; else sum1[rt]=sum1[rt<<1]+sum1[rt<<1|1]; } void push_up2(int rt,int l,int r) { if(cnt[rt]>=2) sum2[rt]=X[r+1]-X[l]; else if(l==r) sum2[rt]=0; else if(cnt[rt]==1) sum2[rt]=sum1[rt<<1]+sum1[rt<<1|1]; else sum2[rt]=sum2[rt<<1]+sum2[rt<<1|1]; } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { cnt[rt]+=c; push_up1(rt,l,r); push_up2(rt,l,r); return ; } int m=(l+r)>>1; if(L<=m) update(L,R,c,lson); if(m<R) update(L,R,c,rson); push_up1(rt,l,r); push_up2(rt,l,r); } void solve(int m) { sort(X,X+m); sort(ss,ss+m); int k=unique(X,X+m)-X; memset(cnt,0,sizeof(cnt)); memset(sum1,0,sizeof(sum1)); memset(sum2,0,sizeof(sum2)); double ret=0; for(int i=0; i<m-1; ++i) { int l=lower_bound(X,X+k,ss[i].l)-X; int r=lower_bound(X,X+k,ss[i].r)-X-1; if(l<=r) update(l,r,ss[i].s,0,k-1,1); ret+=sum2[1]*(ss[i+1].h-ss[i].h); } printf("%.2lf\n",ret); } int main() { int T,n; cin>>T; while(T--) { double x1,y1,x2,y2; int m=0; scanf("%d",&n); while(n--) { scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); X[m]=x1; ss[m++]=Seg(x1,x2,y1,1); X[m]=x2; ss[m++]=Seg(x1,x2,y2,-1); } solve(m); } return 0; }
HUD 1255——覆盖的面积(线段树+面积并多次+离散化)
标签:des style http color io os 使用 ar java
原文地址:http://blog.csdn.net/u014141559/article/details/39667765