http://acm.hdu.edu.cn/showproblem.php?pid=4419
一直想怎么直接处理多个颜色信息,sb了,直接暴力算每种颜色的面积并,再通过容斥原理乱搞计算得到每块的面积即可。
直接开7个大小为N的线段树维护每个颜色会超时,要按每种颜色数量开一个,刚好400ms
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
const int N =2* 10000+500 ;
struct node
{
int flag;
int lx,rx,y,col;
node() {}
node(double a,double b,double c,int d,int cc)
{
lx=a,rx=b,y=c,flag=d;
col=cc;
}
bool operator<(node b)const
{
return y<b.y;
}
};
node line[N],line22[N];
int X[2*N];
struct tree
{
long long sum[4*N];
long long add[4*N];
void build(int l,int r,int rt)
{
if(l == r)
{
sum[rt]=add[rt]=0;
return ;
}
int m = (l + r) >> 1;
build(l,m,2*rt);
build(m+1,r,2*rt+1);
sum[rt]=add[rt]=0;
}
void pushup(int i,int l,int r)
{
if (add[i]) sum[i]=X[r+1]-X[l];
else if (l==r) sum[i]=0;
else sum[i]=sum[i<<1]+sum[i<<1|1];
}
void update(int i, int l, int r, int ql, int qr, int val)
{
if(l > qr || ql > r)
return ;
if(ql<=l&&qr>=r)
{
add[i] += val;
pushup(i,l,r);
return ;
}
int mid = (l + r) >> 1;
update(i << 1, l, mid, ql, qr, val);
update(i << 1 | 1, mid + 1, r, ql, qr, val);
pushup(i,l,r);
}
void init()
{
memset(add,0,sizeof add);
memset(sum,0,sizeof sum);
}
long long cal(node *line,int num)
{
if (num==0) return 0;
// sort(line+1,line+1+num);
int cun_x=0;
for (int i=1; i<=num; i++)
{
if (line[i].flag==1)
X[++cun_x]=line[i].lx,X[++cun_x]=line[i].rx;
}
sort(X+1,X+1+cun_x);
int num_x=unique(X+1,X+1+cun_x)-X-1;
long long ans=0;
build(1,num_x,1);
for (int i=1; i<num; i++)
{
int l=lower_bound(X+1,X+1+num_x,line[i].lx)-X;
int r=lower_bound(X+1,X+1+num_x,line[i].rx)-X-1;
update(1,1,num_x,l,r,line[i].flag);
ans+= 1LL*sum[1]*( line[i+1].y-line[i].y);
}
return ans;
}
};
tree tp;
long long out[8];
long long ans[8];
int main()
{
int n ;
int cnt=1;
int t;
cin>>t;
while(t--)
{
scanf("%d",&n);
int x1,x2,y1,y2;
int num=0;
char s[5];
for (int i=0; i<n; i++)
{
scanf("%s%d%d%d%d",s,&x1,&y1,&x2,&y2);
int col;
if (s[0]=='R') col=1;
if (s[0]=='G') col=2;
if (s[0]=='B') col=4;
line[++num]=node(x1,x2,y1,1,col);
X[num]=x1;
line[++num]=node(x1,x2,y2,-1,col);
X[num]=x2;
}
sort(line+1,line+1+num);
ans[7]=tp.cal(line,num);
int cun=0;
for (int i=1; i<=num; i++) if(line[i].col==1)
line22[++cun]=line[i];
ans[1]=tp.cal(line22,cun);
cun=0;
for (int i=1; i<=num; i++) if(line[i].col==2)
line22[++cun]=line[i];
ans[2]=tp.cal(line22,cun);
cun=0;
for (int i=1; i<=num; i++) if(line[i].col!=4)
line22[++cun]=line[i];
ans[3]=tp.cal(line22,cun);
cun=0;
for (int i=1; i<=num; i++) if(line[i].col==4)
line22[++cun]=line[i];
ans[4]=tp.cal(line22,cun);
cun=0;
for (int i=1; i<=num; i++) if(line[i].col!=2)
line22[++cun]=line[i];
ans[5]=tp.cal(line22,cun);
cun=0;
for (int i=1; i<=num; i++) if(line[i].col!=1)
line22[++cun]=line[i];
ans[6]=tp.cal(line22,cun);
printf("Case %d:\n",cnt++);
out[1]=ans[7]-ans[6];
out[2]=ans[7]-ans[5];
out[4]=ans[7]-ans[3];
out[3]=ans[7]-out[1]-out[2]-ans[4];
out[5]=ans[7]-out[1]-out[4]-ans[2];
out[6]=ans[7]-out[2]-out[4]-ans[1];
out[7]=ans[7]-out[1]-out[2]-out[3]-out[4]-out[5]-out[6];
int j;
j=1;
printf("%lld\n",out[j]);
j=2;
printf("%lld\n",out[j]);
j=4;
printf("%lld\n",out[j]);
j=3;
printf("%lld\n",out[j]);
j=5;
printf("%lld\n",out[j]);
j=6;
printf("%lld\n",out[j]);
j=7;
printf("%lld\n",out[j]);
}
return 0;
}