题意:给你10000个三种颜色的矩形,不同颜色的矩形相互覆盖会形成不同的颜色,问形成的七种颜色的面积是多少。
扫描线。线段树的每个节点里维护好七种颜色的长度。直接暴力跑一次即可。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <algorithm> using namespace std; #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) typedef long long LL; const int N=20005; struct Line { int x,y1,y2,add; Line(){} Line(int x,int y1,int y2,int add) : x(x),y1(y1),y2(y2),add(add) {} bool operator<(const Line &B)const { return x<B.x||x==B.x&&add<B.add; } }; int n,sz; LL ans[10]; vector<int> Y; map<int,int> H; vector<Line> line; struct Segtree { int len[N*4][9],add[N*4][4]; void PushUp(int ind,int lft,int rht) { int s=0; if(add[ind][0]>0) s|=1; if(add[ind][1]>0) s|=2; if(add[ind][2]>0) s|=4; for(int i=1;i<=7;i++) len[ind][i]=0; if(s) { len[ind][s]=len[ind][0]; for(int i=1;i<=7;i++) if(s!=(s|i)) { int tmp=0; if(lft+1!=rht) tmp=len[LL(ind)][i]+len[RR(ind)][i]; len[ind][s|i]+=tmp; len[ind][s]-=tmp; } } else if(lft+1!=rht) { for(int i=1;i<=7;i++) len[ind][i]=len[LL(ind)][i]+len[RR(ind)][i]; } } void build(int lft,int rht,int ind) { for(int i=0;i<=7;i++) { len[ind][i]=0; if(i<3) add[ind][i]=0; } len[ind][0]=Y[rht]-Y[lft]; if(lft+1!=rht) { int mid=MID(lft,rht); build(lft,mid,LL(ind)); build(mid,rht,RR(ind)); } } void updata(int st,int ed,int valu,int lft,int rht,int ind) { if(st<=lft&&rht<=ed) { int key=-1; if(abs(valu)==1) key=0; else if(abs(valu)==2) key=1; else key=2; add[ind][key]+=(valu>0?1:-1); PushUp(ind,lft,rht); } else { int mid=MID(lft,rht); if(st<mid) updata(st,ed,valu,lft,mid,LL(ind)); if(ed>mid) updata(st,ed,valu,mid,rht,RR(ind)); PushUp(ind,lft,rht); } } }seg; void getAns() { for(int i=1;i<=7;i++) ans[i]=0; int len=(int)line.size(); for(int i=0;i<len;i++) { if(i!=0) { for(int j=1;j<=7;j++) ans[j]+=(LL)(line[i].x-line[i-1].x)*seg.len[1][j]; } int y1=H[line[i].y1]; int y2=H[line[i].y2]; int add=line[i].add; seg.updata(y1,y2,add,0,sz-1,1); } } int main() { int t,t_cnt=0; scanf("%d",&t); while(t--) { Y.clear(); H.clear(); line.clear(); scanf("%d",&n); for(int i=0;i<n;i++) { char s[10]; int x1,y1,x2,y2,add; scanf("%s%d%d%d%d",s,&x1,&y1,&x2,&y2); if(s[0]=='R') add=1; else if(s[0]=='G') add=2; else add=4; line.push_back(Line(x1,y1,y2,add)); line.push_back(Line(x2,y1,y2,-add)); Y.push_back(y1); Y.push_back(y2); } sort(line.begin(),line.end()); sort(Y.begin(),Y.end()); Y.erase(unique(Y.begin(),Y.end()),Y.end()); sz=(int)Y.size(); for(int i=0;i<sz;i++) H[Y[i]]=i; seg.build(0,sz-1,1); getAns(); printf("Case %d:\n",++t_cnt); printf("%I64d\n",ans[1]); printf("%I64d\n",ans[2]); printf("%I64d\n",ans[4]); printf("%I64d\n",ans[3]); printf("%I64d\n",ans[5]); printf("%I64d\n",ans[6]); printf("%I64d\n",ans[7]); } return 0; }