题目大意:
给出多个不同颜色的矩形,求最后覆盖的颜色的面积。
思路分析:
我是自己手动暴力枚举。
比赛的时候漏了一种情况。
RGB 可以从 RG+RB组合来(只是举例,就是说可以从两种颜色组合而来)。
然后就只需要维护所有的颜色
用扫描线来判断。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define MAXN 42222 using namespace std; typedef long long ll; struct node { ll s,e,h,type,color;//记录的是每一条线的起点 终点 距离X周的面积 bool operator < (const node &cmp)const { return h<cmp.h; } }line[MAXN]; //是底还是高 底是1高是-1 意味着底就是覆盖。高就是删除 ll tree[MAXN<<2][10]; ll cnt[MAXN<<2][10]; ll x[MAXN<<2]; void pushup(int num,int l,int r) { int chs=0; for(int i=0;i<3;i++) { if(cnt[num][i]) chs|=(1<<i); } if(chs==0) { if(l==r) { for(int i=0;i<7;i++) tree[num][i]=0; return; } for(int i=0;i<7;i++) tree[num][i]=tree[num<<1][i]+tree[num<<1|1][i]; } else if(chs==1) { if(l==r) { for(int i=0;i<7;i++) { if(i==0)tree[num][i]=x[r+1]-x[l]; else tree[num][i]=0; } return; } tree[num][1]=0; tree[num][2]=0; tree[num][3]=tree[num<<1][1]+tree[num<<1|1][1]+tree[num<<1][3]+tree[num<<1|1][3]; tree[num][4]=tree[num<<1][2]+tree[num<<1|1][2]+tree[num<<1][4]+tree[num<<1|1][4]; tree[num][5]=0; tree[num][6]=tree[num<<1][5]+tree[num<<1|1][5]+tree[num<<1][6]+tree[num<<1|1][6]; ll tmp=x[r+1]-x[l]; for(int i=0;i<=6;i++)if(i!=0)tmp-=tree[num][i]; tree[num][0]=tmp; } else if(chs==2) { if(l==r) { for(int i=0;i<7;i++) { if(i==1)tree[num][i]=x[r+1]-x[l]; else tree[num][i]=0; } return; } tree[num][0]=tree[num][2]=0; tree[num][3]=tree[num<<1][0]+tree[num<<1|1][0]+tree[num<<1][3]+tree[num<<1|1][3]; tree[num][4]=0; tree[num][5]=tree[num<<1][2]+tree[num<<1|1][2]+tree[num<<1][5]+tree[num<<1|1][5]; tree[num][6]=tree[num<<1][4]+tree[num<<1|1][4]+tree[num<<1][6]+tree[num<<1|1][6]; ll tmp=x[r+1]-x[l]; for(int i=0;i<=6;i++)if(i!=1)tmp-=tree[num][i]; tree[num][1]=tmp; } else if(chs==3) { if(l==r) { for(int i=0;i<7;i++) { if(i==3)tree[num][i]=x[r+1]-x[l]; else tree[num][i]=0; } return; } tree[num][0]=tree[num][2]=tree[num][1]=0; tree[num][4]=0; tree[num][5]=0; tree[num][6]=tree[num<<1][2]+tree[num<<1|1][2]+tree[num<<1][6]+tree[num<<1|1][6]+tree[num<<1][4]+tree[num<<1|1][4]+tree[num<<1][5]+tree[num<<1|1][5]; ll tmp=x[r+1]-x[l]; for(int i=0;i<=6;i++)if(i!=3)tmp-=tree[num][i]; tree[num][3]=tmp; } else if(chs==4) { if(l==r) { for(int i=0;i<7;i++) { if(i==2)tree[num][i]=x[r+1]-x[l]; else tree[num][i]=0; } return; } tree[num][0]=tree[num][1]=0; tree[num][3]=0; tree[num][4]=tree[num<<1][0]+tree[num<<1|1][0]+tree[num<<1][4]+tree[num<<1|1][4]; tree[num][5]=tree[num<<1][1]+tree[num<<1|1][1]+tree[num<<1][5]+tree[num<<1|1][5]; tree[num][6]=tree[num<<1][3]+tree[num<<1|1][3]+tree[num<<1][6]+tree[num<<1|1][6]; ll tmp=x[r+1]-x[l]; for(int i=0;i<=6;i++)if(i!=2)tmp-=tree[num][i]; tree[num][2]=tmp; } else if(chs==5) { if(l==r) { for(int i=0;i<7;i++) { if(i==4)tree[num][i]=x[r+1]-x[l]; else tree[num][i]=0; } return; } tree[num][0]=tree[num][2]=tree[num][1]=0; tree[num][3]=0; tree[num][5]=0; tree[num][6]=tree[num<<1][1]+tree[num<<1|1][1]+tree[num<<1][6]+tree[num<<1|1][6]+tree[num<<1][3]+tree[num<<1|1][3]+tree[num<<1][5]+tree[num<<1|1][5]; ll tmp=x[r+1]-x[l]; for(int i=0;i<=6;i++)if(i!=4)tmp-=tree[num][i]; tree[num][4]=tmp; } else if(chs==6) { if(l==r) { for(int i=0;i<7;i++) { if(i==5)tree[num][i]=x[r+1]-x[l]; else tree[num][i]=0; } return; } tree[num][0]=tree[num][2]=tree[num][1]=0; tree[num][3]=0; tree[num][4]=0; tree[num][6]=tree[num<<1][0]+tree[num<<1|1][0]+tree[num<<1][6]+tree[num<<1|1][6]+tree[num<<1][3]+tree[num<<1|1][3]+tree[num<<1][4]+tree[num<<1|1][4]; ll tmp=x[r+1]-x[l]; for(int i=0;i<=6;i++)if(i!=5)tmp-=tree[num][i]; tree[num][5]=tmp; } else if(chs==7) { if(l==r) { for(int i=0;i<7;i++) { if(i==6)tree[num][i]=x[r+1]-x[l]; else tree[num][i]=0; } return; } tree[num][0]=tree[num][2]=tree[num][1]=0; tree[num][3]=0; tree[num][4]=0; tree[num][5]=0; tree[num][6]=x[r+1]-x[l]; } } void update(int num,int s,int e,int l,int r,ll val,ll color) { if(l<=s && r>=e) { cnt[num][color]+=val; pushup(num,s,e); return ; } int mid=(s+e)>>1; if(l<=mid)update(num<<1,s,mid,l,r,val,color); if(r>mid)update(num<<1|1,mid+1,e,l,r,val,color); pushup(num,s,e); } void debug(int num,int s,int e) { printf("s = %d e = %d\n",s,e); for(int i=0;i<=6;i++)printf("%d ",tree[num][i]); puts(""); if(s==e)return; int mid=(s+e)>>1; debug(num<<1,s,mid); debug(num<<1|1,mid+1,e); } ll ans[7]; int main() { int n,T; int cas=1; for(scanf("%d",&T);T--;) { scanf("%d",&n); int m=0; for(int i=1;i<=n;i++) { char str[5]; ll x1,y1,x2,y2; scanf("%s%I64d%I64d%I64d%I64d",str,&x1,&y1,&x2,&y2); ll co; if(str[0]=='R')co=0; else if(str[0]=='G')co=1; else if(str[0]=='B')co=2; m++; x[m]=x1; line[m].s=x1,line[m].e=x2,line[m].h=y1,line[m].type=1,line[m].color=co; m++; x[m]=x2; line[m].s=x1,line[m].e=x2,line[m].h=y2,line[m].type=-1,line[m].color=co; } sort(line+1,line+1+m); sort(x+1,x+1+m); int tot=unique(x+1,x+1+m)-x-1; memset(ans,0,sizeof ans); memset(tree,0,sizeof tree); memset(cnt,0,sizeof cnt); for(int i=1;i<m;i++) { int L=lower_bound(x+1,x+tot+1,line[i].s)-x; int R=lower_bound(x+1,x+tot+1,line[i].e)-x-1; if(L<=R)update(1,1,tot,L,R,line[i].type,line[i].color); for(int j=0;j<=6;j++) ans[j]+=tree[1][j]*(line[i+1].h-line[i].h); } printf("Case %d:\n",cas++); for(int i=0;i<=6;i++) printf("%I64d\n",ans[i]); } return 0; }
时间: 2024-10-11 04:12:37