求http://acm.hdu.edu.cn/showproblem.php?pid=4419
求不同顏色的覆蓋面積。
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef __int64 lld;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 65537;
lld sum[maxn][1<<3];
int x[20010];
int cover[maxn][4];
struct seg {
int l,r,h,flag;
seg(){}
seg(int _l,int _r,int _h,int _flag):l(_l),r(_r),h(_h),flag(_flag){}
bool operator < (const seg &cmp) const {
if(h!=cmp.h) return h<cmp.h;
return flag<cmp.flag;
}
}ss[20010];
inline void pushup(int rt,int l,int r) {
int s=0,i;// 有cover表示這個區間被完全覆蓋了, 不能由子區間來改變
for(i=1;i<=3;i++) if(cover[rt][i]) s|=1<<(i-1);//和子區間沒關係的狀態
for(i=0;i<8;i++) sum[rt][i]=0;
if(l==r) {
sum[rt][s]=x[r+1]-x[l];
} else {
for(i=0;i<8;i++) /* keys */
sum[rt][i|s] += sum[rt<<1][i] + sum[rt<<1|1][i];
}
}
void update(int L,int R,int c,int l,int r,int rt) {
if(L <= l && r <= R){
if(c>0) cover[rt][c]++;
else cover[rt][-c]--;
pushup(rt,l,r);
return ;
}
int m=l+r>>1;
if(L <= m) update(L,R,c,lson);
if(R > m) update(L,R,c,rson);
pushup(rt,l,r);
}
void build(int l,int r,int rt) {
int i;
for(i=1;i<=3;i++) cover[rt][i]=0;
for(i=1;i<8;i++) sum[rt][i]=0;
sum[rt][0]=x[r+1]-x[l];
if(l==r) { return ;}
int m=l+r>>1;
build(lson);
build(rson);
}
lld ans[1<<3];
int main() {
char col[5];
int n,i,j,tot,ca=1,t,flag;
int x1,y1,x2,y2;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(i=1,tot=0;i<=n;i++) {
scanf("%s%d%d%d%d",col,&x1,&y1,&x2,&y2);
x[tot]=x1;
if(col[0]=='R') flag=1;
else if(col[0]=='G') flag=2;
else flag=3;
ss[tot++]=seg(x1,x2,y1,flag);
x[tot]=x2;
ss[tot++]=seg(x1,x2,y2,-flag);
}
sort(x,x+tot);
sort(ss,ss+tot);
n=unique(x,x+tot)-x;
build(0,n-2,1);
memset(ans,0,sizeof(ans));
for(i=0;i<tot-1;i++) {
int left=lower_bound(x,x+n,ss[i].l)-x;
int right=lower_bound(x,x+n,ss[i].r)-x-1;
update(left,right,ss[i].flag,0,n-2,1);
for(j=1;j<8;j++) ans[j]+=sum[1][j]*(ss[i+1].h-ss[i].h);
}
printf("Case %d:\n",ca++);
printf("%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n",ans[1],ans[2],ans[4],ans[3],ans[5],ans[6],ans[7]);
}
return 0;
}