Posters
Problem Description
有很多海报,每个海报都被减去了一个矩形(可能全减),现在给出没张海报的位置,求它们的面积并。
保证坐标在(0, 0)到(50000, 50000)之间。没有海报斜着贴,减去的矩形边与x,y轴平行。
Input
有很多数据。
对于每组数据第一行有一个整数N (0<N<=50000)表示海报数 接下来n行,每行8个整数 x1, y1, x2, y2, x3, y3, x4, y4, 表示每张海报的左下角坐标(x1, y1),右上角坐标(x2, y2) ,减去的矩形左上角坐标(x3, y3),右上角坐标(x4, y4)(0<=xi, yi<=50000(i=1…4) and x1<=x3<x4<=x2, y1<=y3<y4<=y2).
数据以0结尾。
Output
对于每组数据输出一行,表示它们的面积并。
Sample Input
2 0 0 10 10 1 1 9 9 2 2 8 8 3 3 7 7 0
Sample Output
56
这题就是要把矩形差分成如下形式:
然后进行矩形面积并:
谨记问题转化后各数组的大小。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<cctype> #include<iostream> #include<functional> #include<algorithm> using namespace std; #define MAXN (50000+10) #define MAXT (MAXN*5) #define MAXXi (50000+10) #define Lson (x<<1) #define Rson ((x<<1)^1) int hpos[MAXN]; int x[MAXN*4]={0}; struct SegMent { int x1,x2,h,type; SegMent(){} SegMent(int _x1,int _x2,int _h,int _type):x1(_x1),x2(_x2),h(_h),type(_type){} friend bool operator<(const SegMent a,const SegMent b){return a.h<b.h;} }; int n,size; struct SegMent_array { SegMent a[MAXN*8]; int size; SegMent_array():size(0) { memset(a,0,sizeof(a)); } bool add(int x1,int x2,int y1,int y2) { if (x1==x2||y1==y2) return 0; else { a[++size]=SegMent(x1,x2,y1,1); a[++size]=SegMent(x1,x2,y2,-1); return 1; } } }a; struct SegMentTree { long long sum[MAXT],cnt[MAXT],len[MAXT]; int M,n; void fillchar(int _n) { n=_n; M=1;while (M-2<n) M<<=1; memset(sum,0,sizeof(sum)); memset(cnt,0,sizeof(cnt)); memset(len,0,sizeof(len)); for (int i=M+1;i<=M+n;i++) len[i]=x[i-M+1]-x[i-M]; for (int i=M-1;i>=1;i--) len[i]=len[i<<1]+len[(i<<1)^1]; } void pushup(int x) { sum[x]=(cnt[x])?(len[x]):((x<M)?(sum[Lson]+sum[Rson]):0); } void update(int x) { while (x) { pushup(x);x>>=1; } } void insert(int l,int r,long long c) { if (l>r) return ; l=l-1+M;r=r+1+M; int ll=l,rr=r; for (;l^r^1;l>>=1,r>>=1) { if (~l&1) {cnt[l+1]+=c; pushup(l+1);} if (r&1) {cnt[r-1]+=c; pushup(r-1);} } // cout<<endl<<"Push:"<<ll<<' '<<rr<<endl; update(ll);update(rr); } void print() { for (int i=1;i<=2*M;i++) if (sum[i]) cout<<i<<':'<<sum[i]<<' '; cout<<endl; for (int i=1;i<=2*M;i++) if (cnt[i]) cout<<i<<':'<<cnt[i]<<' '; cout<<endl; cout<<endl; } }t; int main() { // freopen("Hdu3265.in","r",stdin); while (scanf("%d",&n)!=EOF) { if (n==0) break; for (int i=1;i<=n;i++) { int x1,y1,x2,y2,x3,y3,x4,y4; scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4); a.add(x1,x3,y1,y4); a.add(x3,x2,y1,y3); a.add(x1,x4,y4,y2); a.add(x4,x2,y3,y2); x[i*4-3]=x1;x[i*4-2]=x2;x[i*4-1]=x3;x[i*4]=x4; } sort(x+1,x+4*n+1); size=unique(x+1,x+4*n+1)-(x+1); /* for (int i=1;i<=size;i++) cout<<x[i]<<' '; cout<<endl; */ // cout<<size; for (int i=1;i<=size;i++) hpos[x[i]]=i; t.fillchar(size-1); sort(a.a+1,a.a+1+a.size); // cout<<'s'; // for (int i=1;i<=a.size;i++) cout<<a.a[i].x1<<' '<<a.a[i].x2<<' '<<a.a[i].h<<' '<<a.a[i].type<<endl; long long ans=0; for (int i=1;i<=a.size;i++) { ans+=t.sum[1]*((long long)a.a[i].h-a.a[i-1].h); t.insert(hpos[a.a[i].x1],hpos[a.a[i].x2]-1,a.a[i].type); /* cout<<a.a[i].x1<<' '<<a.a[i].x2<<' '<<a.a[i].h<<' '<<a.a[i].type<<endl; cout<<ans<<endl; t.print(); */ } cout<<ans<<endl; a.size=0; } return 0; }