http://acm.hdu.edu.cn/showproblem.php?pid=3265
面积并。
线段树+扫描线,坐标为小于50000的int型,所以没必要离散化
View Code
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 typedef __int64 LL; 6 const int N=50010*4; 7 struct segment 8 { 9 int x1,x2,y; 10 int d; 11 segment(){} 12 segment(int _x1,int _x2,int _y,int _d) 13 :x1(_x1),x2(_x2),y(_y),d(_d){} 14 bool operator < (const segment &a)const 15 { 16 return y<a.y; 17 } 18 }seg[N*2]; 19 20 struct segtree 21 { 22 int l,r,c; 23 int s; 24 }st[N]; 25 #define lch rt<<1 26 #define rch rt<<1|1 27 void build(int l,int r,int rt) 28 { 29 st[rt].l=l, st[rt].r=r; 30 st[rt].s=st[rt].c=0; 31 if(l==r) return; 32 int m=(l+r)/2; 33 build(l,m,lch); 34 build(m+1,r,rch); 35 } 36 void pushup(int rt) 37 { 38 if(st[rt].c) st[rt].s=st[rt].r-st[rt].l+1; 39 else 40 { 41 if(st[rt].l==st[rt].r) st[rt].s=0; 42 else st[rt].s=st[lch].s+st[rch].s; 43 } 44 } 45 void update(int L,int R,int x,int rt) 46 { 47 int l=st[rt].l, r=st[rt].r; 48 if(L<=l && r<=R) 49 { 50 st[rt].c+=x; 51 pushup(rt); 52 return; 53 } 54 int m=(l+r)/2; 55 if(L<=m) update(L,R,x,lch); 56 if(R>m) update(L,R,x,rch); 57 pushup(rt); 58 } 59 int main() 60 { 61 int n; 62 while(scanf("%d",&n),n) 63 { 64 int ns=0,maxx=0;; 65 for(int i=0;i<n;i++) 66 { 67 int x1,y1,x2,y2,x3,y3,x4,y4; 68 scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4); 69 if(x2>maxx) maxx=x2; 70 seg[ns++]=segment(x1+1,x3,y1,1); 71 seg[ns++]=segment(x1+1,x3,y2,-1); 72 seg[ns++]=segment(x4+1,x2,y1,1); 73 seg[ns++]=segment(x4+1,x2,y2,-1); 74 seg[ns++]=segment(x3+1,x4,y1,1); 75 seg[ns++]=segment(x3+1,x4,y3,-1); 76 seg[ns++]=segment(x3+1,x4,y4,1); 77 seg[ns++]=segment(x3+1,x4,y2,-1); 78 } 79 sort(seg,seg+ns); 80 build(1,maxx,1); 81 LL ans=0; 82 for(int i=0;i<ns;i++) 83 { 84 update(seg[i].x1,seg[i].x2,seg[i].d,1); 85 ans+=(LL)st[1].s*(seg[i+1].y-seg[i].y); 86 } 87 printf("%I64d\n",ans); 88 } 89 return 0; 90 }