hdu 4419 2012杭州网络赛

来源:互联网 发布:淘宝dsr多久更新一次 编辑:程序博客网 时间:2024/05/17 09:13

题目大意:给出一些有颜色的矩形,会重叠,问最后每种颜色的面积为多少。。

当时网络赛不会做,最近学习了一下大神的做法,总算明白了。

我们可以将 三基色 RGB 以及其 衍生出来的其他颜色 化成 二进制表示 xxx,三位分别表示BGB ,那么 001 就是 R,010就是G,

100就是B,011就是 RG。。。以此类推,就构成了7个状态,开辟线段树,记录每个区间每种颜色的 长度用扫描线从左往右扫描

即可。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 10005#define lson u<<1#define rson u<<1|1#define CLR(a,b) memset(a,0,sizeof(a))#define LL long longint x[MAXN<<1];LL ans[8];struct segment{int x1,x2,y,val;segment(){}segment(int a,int b,int c,int d):x1(a),x2(b),y(c),val(d){}bool operator < (const segment& cmp)const{return y<cmp.y;}}seg[MAXN<<1];struct Node{int lef,rig,len[8],cnt[5];//len记录每种颜色的长度,cnt记录RGB三基色是否存在}T[MAXN<<3];void Build(int u,int l,int r){T[u].lef=l;T[u].rig=r;CLR(T[u].len,0);CLR(T[u].cnt,0);if(l==r)return;int mid=(l+r)>>1;Build(lson,l,mid);Build(rson,mid+1,r);}void PushUp(int u){CLR(T[u].len,0);//叶子节点,长度为清0int state=(T[u].cnt[1]>0?1:0)|(T[u].cnt[2]>0?2:0)|(T[u].cnt[4]>0?4:0);//三基色混在一起生成的状态,或操作if(state){T[u].len[state]+=x[T[u].rig]-x[T[u].lef-1];//记录混合色的长度for(int i=1;i<8;i++){if(state!=(state|i)){//判断原来是否还有其他颜色int tmp=T[lson].len[i]+T[rson].len[i];T[u].len[state|i]+=tmp;//新混合色长度增加T[u].len[state]-=tmp;//原来的颜色减少}}}//如果本区间没有三基色,那么本区间的颜色长度将直接从左右儿子获得else if(T[u].lef!=T[u].rig)for(int i=1;i<8;i++)T[u].len[i]=T[lson].len[i]+T[rson].len[i];}void Update(int u,int l,int r,int val){if(l<=T[u].lef&&T[u].rig<=r){val>0?++T[u].cnt[val]:--T[u].cnt[-val];}else {if(l<=T[lson].rig)Update(lson,l,r,val);if(r>=T[rson].lef)Update(rson,l,r,val);}PushUp(u);}int main(){int t,n;char color;int x1,y1,x2,y2;scanf("%d",&t);for(int cas=1;cas<=t;cas++){scanf("%d",&n);int num=0;for(int i=0;i<n;i++){scanf(" %c%d%d%d%d",&color,&x1,&y1,&x2,&y2);x[num]=x1;seg[num++]=segment(x1,x2,y1,color=='R'?1:(color=='G'?2:4));x[num]=x2;seg[num++]=segment(x1,x2,y2,color=='R'?-1:(color=='G'?-2:-4));}sort(x,x+num);sort(seg,seg+num);int xnum=unique(x,x+num)-x;//去重Build(1,1,xnum);CLR(ans,0);for(int i=0;i<num;i++){int l=lower_bound(x,x+xnum,seg[i].x1)-x+1;//离散化。。int r=lower_bound(x,x+xnum,seg[i].x2)-x;Update(1,l,r,seg[i].val);if(seg[i].y!=seg[i+1].y)for(int j=1;j<8;j++)ans[j]+=(LL)(seg[i+1].y-seg[i].y)*T[1].len[j];}printf("Case %d:\n",cas);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]);}}


原创粉丝点击