/*
和胡浩大牛写的hdu 1255题的大体思路差不多,先把矩形线段化,在一个数轴上覆盖,再枚举另一个数轴求面积(再枚举之前先排好序),只不过这题的状态比较多,要把Pushup函数改一下,这里不仅仅是处理覆盖一次和多次的问题了,还要考虑颜色的重叠问题,处理的时候有点像容斥,用二进制的1,2,4表示r,g,b这样便于处理,最后覆盖过程就大体差不多了;
代码如下:
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=20000;
const int t[8]={0,1,2,4,3,5,6,7};
struct tree{__int64 n[8];} sum[N<<2];
struct seg{
__int64 x1,x2,h,v;
bool operator <(const seg &tem) const
{return h<tem.h;}
} line[N];
__int64 X[N];
__int64 cnt[N<<2][4];
void Set(int k,__int64 x1,__int64 y1,__int64 x2,__int64 y2,int v)
{
X[k]=x1;
X[k+1]=x2;
line[k].x1=x1;line[k].x2=x2;line[k].h=y1;line[k].v=v;
line[k+1].x1=x1;line[k+1].x2=x2;line[k+1].h=y2;line[k+1].v=-v;
}
void Pushup(int i,int l,int r)
{
int j,R=1,G=2,B=4,k=0;
__int64 tem;
if(cnt[i][1]>0)k|=R;
if(cnt[i][2]>0)k|=G;
if(cnt[i][3]>0)k|=B;
memset(sum[i].n,0,sizeof(sum[i].n));
if(k)
{
sum[i].n[k]=X[r+1]-X[l];
if(l==r)return;
for(j=1;j<=7;j++)//主要思路在这个循环,这里参考了各个大牛的思路,很简洁,很漂亮;
{
if((k|j)!=k){
tem=sum[i<<1].n[j]+sum[i<<1|1].n[j];
sum[i].n[k]-=tem;
sum[i].n[k|j]+=tem;
}
}
}
else if(l<r)
for(j=1;j<=7;j++)sum[i].n[j]=sum[i<<1].n[j]+sum[i<<1|1].n[j];
}
void update(int i,int l,int r,int a,int b,int v)
{
if(l==a&&r==b)
{
if(v<0) --cnt[i][-v];
else ++cnt[i][v];
Pushup(i,l,r);
return ;
}
int mid=(l+r)>>1;
if(b<=mid) update(i<<1,l,mid,a,b,v);
else if(b>mid&&a<=mid)
{
update(i<<1,l,mid,a,mid,v);
update(i<<1|1,mid+1,r,mid+1,b,v);
}
else update(i<<1|1,mid+1,r,a,b,v);
Pushup(i,l,r);
}
int Bin(int l,int r,__int64 v)
{
int mid;
while(l<=r)
{
mid=(l+r)>>1;
if(X[mid]==v) return mid;
else if(X[mid]>v) r=mid-1;
else l=mid+1;
}
return -1;
}
int main()
{
char op[5];
int cas,cass,n,k,m,i,j;
__int64 x1,x2,y1,y2,ans[8];
scanf("%d",&cass);
for(cas=1;cas<=cass;cas++)
{
m=0;
scanf("%d",&n);
while(n--)
{
scanf("%s%I64d%I64d%I64d%I64d",op,&x1,&y1,&x2,&y2);
if(op[0]=='R')k=1;
if(op[0]=='G')k=2;
if(op[0]=='B')k=3;
Set(m,x1,y1,x2,y2,k);
m+=2;
}
sort(X,X+m);
sort(line,line+m);
for(i=k=1;i<m;i++)
if(X[i-1]<X[i])
X[k++]=X[i];
int l,r;
memset(ans,0,sizeof(ans));
memset(cnt,0,sizeof(cnt));
memset(sum,0,sizeof(sum));
for(i=0;i<m-1;i++)
{
l=Bin(0,k-1,line[i].x1);
r=Bin(0,k-1,line[i].x2)-1;
if(l<=r)update(1,0,k-1,l,r,line[i].v);
for(j=1;j<=7;j++)
ans[j]+=sum[1].n[j]*(line[i+1].h-line[i].h);
}
printf("Case %d:\n",cas);
for(i=1;i<=7;i++)
printf("%I64d\n",ans[t[i]]);
}
return 0;
}
/*
10
2
G 0 0 2 2
B 1 1 3 3
*/