Problem D
1 2 0 0 10 10 1 1 9 9 2 2 8 8 3 3 7 7
56
/*扫描线求矩形面积的并 刚开始的不会,后来看了会资料,又请教了几个大神,终于是学会了 我把矩形分解成x方向的两条线段,然后从y轴开始由小到大扫描*/ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<stack> #include<queue> #define N 50550 #define INF 10000000 using namespace std; struct data1 //记录线段 { int x1,x2,y; int fg; //出边 -1 ; 入边 1 } line[8*N]; struct data2 //记录线段树 { int be,en,len,bj; } tree[4*N]; void qsort(int st,int en) //对线段从小到大排序 { int i=st,j=en; line[0]=line[i]; while(i<j) { while(i<j && line[0].y<=line[j].y) j--; if(i<j) { line[i]=line[j]; i++; } while(i<j && line[0].y>=line[i].y) i++; if(i<j) { line[j]=line[i]; j--; } } line[i]=line[0]; if(st<i-1) qsort(st,i-1); if(i+1<en) qsort(i+1,en); } void add_line(int x1,int x2,int y,int fg,int *tot) //在线段集合中添加线段 { if(x1==x2) return; (*tot)++; line[*tot].x1=x1,line[*tot].x2=x2,line[*tot].y=y,line[*tot].fg=fg; } void make_tree(int v,int be,int en) //建树 { tree[v].be=be; tree[v].en=en; tree[v].bj=tree[v].len=0; if(be==en) return; int mid=(be+en)>>1; make_tree(v<<1,be,mid); make_tree((v<<1)+1,mid+1,en); } void clear(int v) //对线段树的节点的标记域进行传递 { if(tree[v].bj!=0) tree[v].len=tree[v].en-tree[v].be+1; else if(tree[v].be==tree[v].en) tree[v].len=0; else tree[v].len=tree[v<<1].len+tree[(v<<1)+1].len; } void update(int v,int x1,int x2,int fg) //更新线段树中 [x1,x2] 的线段 { if(x1<=tree[v].be && x2>=tree[v].en) { tree[v].bj+=fg; clear(v); return; } int mid=(tree[v].be+tree[v].en)>>1; if(x2<=mid) update(v<<1,x1,x2,fg); else if(x1>mid) update((v<<1)+1,x1,x2,fg); else { update(v<<1,x1,x2,fg); update((v<<1)+1,x1,x2,fg); } clear(v); } int main() { int t; int n,x1,x2,x3,x4,y1,y2,y3,y4; scanf("%d",&t); while(t--) { memset(line,0,sizeof(line)); memset(tree,0,sizeof(tree)); int tot=0; scanf("%d",&n); for(int i=1;i<=n;i++) //将回字形的区域分割成四个矩形 { scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4); add_line(x1,x3,y1,1,&tot); add_line(x1,x3,y2,-1,&tot); add_line(x3,x4,y1,1,&tot); add_line(x3,x4,y3,-1,&tot); add_line(x3,x4,y4,1,&tot); add_line(x3,x4,y2,-1,&tot); add_line(x4,x2,y1,1,&tot); add_line(x4,x2,y2,-1,&tot); } qsort(1,tot); make_tree(1,1,N-1); __int64 ans=0; line[0]=line[1]; for(int i=1;i<=tot;i++) //统计面积的和 { ans+=(__int64)tree[1].len*(line[i].y-line[i-1].y); update(1,line[i].x1+1,line[i].x2,line[i].fg); } printf("%I64d\n",ans); } return 0; }