由于状态有点多,我们用状压的思想来做这道题,用1,2,4分别来表示三原色,其他的就和线扫描一样了!这样是比较简单的做法了,当然也可以用最原始的做法!不过嘛就是有点麻烦了!
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define nn 10005
#define LL __int64
#define root 1,m,1
int biao[300];
struct seg
{
int l,r,h,f,rbg;
}s[nn<<1];
int pos[nn<<1];
int col[nn<<4][8];
int yan[nn<<4][3];
bool cmp(seg a,seg b)
{
return a.h<b.h;
}
int binary(int v,int low,int top)
{
while(low<=top)
{
int mid=(low+top)>>1;
if(pos[mid]==v) return mid;
else if(pos[mid]>v) top=mid;
else low=mid+1;
}
return -1;
}
void pushup(int l,int r,int rt)
{
int t=0;
for(int i=0;i<3;i++)
if(yan[rt][i])
t=t|(1<<i);//表示该区间的状态
for(int i=0;i<8;i++)
col[rt][i]=0;
int all=pos[r+1]-pos[l];
for(int i=1;i<8;i++)
col[rt][i|t]+=col[rt<<1][i]+col[rt<<1|1][i];//i|t表示由i更可得到的状态
for(int i=1;i<8;i++)
all-=col[rt][i];
col[rt][t]+=all;//未更新的表示只有改颜色的长度
}
void updata(int ll,int rr,int cl,int x,int l,int r,int rt)
{
if(ll>r||rr<l) return;
if(ll<=l&&r<=rr)
{
yan[rt][cl]+=x;
pushup(l,r,rt);
return;
}
int mid=(l+r)>>1;
updata(ll,rr,cl,x,l,mid,rt<<1);
updata(ll,rr,cl,x,mid+1,r,rt<<1|1);
pushup(l,r,rt);
}
int main()
{
biao['R']=0;
biao['G']=1;
biao['B']=2;
int t;
int Case=1;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int num=0;
for(int i=0;i<n;i++)
{
char a[2];
int x1,x2,y1,y2;
scanf("%s%d%d%d%d",a,&x1,&y1,&x2,&y2);
s[num].l=x1; s[num].r=x2; s[num].h=y1; s[num].f=1; s[num++].rbg=biao[a[0]];
s[num].l=x1; s[num].r=x2; s[num].h=y2; s[num].f=-1; s[num].rbg=biao[a[0]];
pos[num-1]=x1; pos[num++]=x2;
}
sort(pos,pos+num);
sort(s,s+num,cmp);
int m=1;
for(int i=1;i<num;i++)
{
if(pos[i]!=pos[i-1])
pos[m++]=pos[i];
}
LL ans[8];
memset(yan,0,sizeof(yan));
memset(col,0,sizeof(col));
memset(ans,0,sizeof(ans));
int st=0;
for(int i=0;i<num;i++)
{
int l=binary(s[i].l,0,m-1);
int r=binary(s[i].r,0,m-1)-1;
for(int j=1;j<8;j++)
ans[j]+=(LL)col[1][j]*(s[i].h-st);
st=s[i].h;
updata(l,r,s[i].rbg,s[i].f,0,m-1,1);
}
printf("Case %d:\n",Case++);
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;
}