题意:给你10000个三种颜色的矩形,不同颜色的矩形相互覆盖会形成不同的颜色,问形成的七种颜色的面积是多少。
扫描线。线段树的每个节点里维护好七种颜色的长度。直接暴力跑一次即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
typedef long long LL;
const int N=20005;
struct Line
{
int x,y1,y2,add;
Line(){}
Line(int x,int y1,int y2,int add) :
x(x),y1(y1),y2(y2),add(add) {}
bool operator<(const Line &B)const
{
return x<B.x||x==B.x&&add<B.add;
}
};
int n,sz;
LL ans[10];
vector<int> Y;
map<int,int> H;
vector<Line> line;
struct Segtree
{
int len[N*4][9],add[N*4][4];
void PushUp(int ind,int lft,int rht)
{
int s=0;
if(add[ind][0]>0) s|=1;
if(add[ind][1]>0) s|=2;
if(add[ind][2]>0) s|=4;
for(int i=1;i<=7;i++) len[ind][i]=0;
if(s)
{
len[ind][s]=len[ind][0];
for(int i=1;i<=7;i++) if(s!=(s|i))
{
int tmp=0;
if(lft+1!=rht) tmp=len[LL(ind)][i]+len[RR(ind)][i];
len[ind][s|i]+=tmp;
len[ind][s]-=tmp;
}
}
else if(lft+1!=rht)
{
for(int i=1;i<=7;i++) len[ind][i]=len[LL(ind)][i]+len[RR(ind)][i];
}
}
void build(int lft,int rht,int ind)
{
for(int i=0;i<=7;i++)
{
len[ind][i]=0;
if(i<3) add[ind][i]=0;
}
len[ind][0]=Y[rht]-Y[lft];
if(lft+1!=rht)
{
int mid=MID(lft,rht);
build(lft,mid,LL(ind));
build(mid,rht,RR(ind));
}
}
void updata(int st,int ed,int valu,int lft,int rht,int ind)
{
if(st<=lft&&rht<=ed)
{
int key=-1;
if(abs(valu)==1) key=0;
else if(abs(valu)==2) key=1;
else key=2;
add[ind][key]+=(valu>0?1:-1);
PushUp(ind,lft,rht);
}
else
{
int mid=MID(lft,rht);
if(st<mid) updata(st,ed,valu,lft,mid,LL(ind));
if(ed>mid) updata(st,ed,valu,mid,rht,RR(ind));
PushUp(ind,lft,rht);
}
}
}seg;
void getAns()
{
for(int i=1;i<=7;i++) ans[i]=0;
int len=(int)line.size();
for(int i=0;i<len;i++)
{
if(i!=0)
{
for(int j=1;j<=7;j++)
ans[j]+=(LL)(line[i].x-line[i-1].x)*seg.len[1][j];
}
int y1=H[line[i].y1];
int y2=H[line[i].y2];
int add=line[i].add;
seg.updata(y1,y2,add,0,sz-1,1);
}
}
int main()
{
int t,t_cnt=0;
scanf("%d",&t);
while(t--)
{
Y.clear(); H.clear();
line.clear();
scanf("%d",&n);
for(int i=0;i<n;i++)
{
char s[10];
int x1,y1,x2,y2,add;
scanf("%s%d%d%d%d",s,&x1,&y1,&x2,&y2);
if(s[0]=='R') add=1;
else if(s[0]=='G') add=2;
else add=4;
line.push_back(Line(x1,y1,y2,add));
line.push_back(Line(x2,y1,y2,-add));
Y.push_back(y1); Y.push_back(y2);
}
sort(line.begin(),line.end());
sort(Y.begin(),Y.end());
Y.erase(unique(Y.begin(),Y.end()),Y.end());
sz=(int)Y.size();
for(int i=0;i<sz;i++) H[Y[i]]=i;
seg.build(0,sz-1,1);
getAns();
printf("Case %d:\n",++t_cnt);
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;
}