hdu 4419 2012杭州网络赛
2012-10-28 10:36
260 查看
题目大意:给出一些有颜色的矩形,会重叠,问最后每种颜色的面积为多少。。
当时网络赛不会做,最近学习了一下大神的做法,总算明白了。
我们可以将 三基色 RGB 以及其 衍生出来的其他颜色 化成 二进制表示 xxx,三位分别表示BGB ,那么 001 就是 R,010就是G,
100就是B,011就是 RG。。。以此类推,就构成了7个状态,开辟线段树,记录每个区间每种颜色的 长度,用扫描线从左往右扫描
即可。
当时网络赛不会做,最近学习了一下大神的做法,总算明白了。
我们可以将 三基色 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 long int 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);//叶子节点,长度为清0 int 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]); } }
相关文章推荐
- hdu 4412 2012杭州赛区网络赛 期望
- hdu 4419 Colourful Rectangle (2012杭州区域赛 1010 )
- HDU 4417 Super Mario(2012杭州网络赛 H 离线线段树)
- hdu 4414 2012杭州网络赛
- hdu 4410 Boomerang (2012杭州网络赛1001)
- hdu 4417 2012杭州网络赛
- HDU 4410 Boomerang(计算几何)(2012杭州网络赛1001)
- HDU 4416 Good Article Good sentence 2012 杭州网络赛
- hdu 4417 2012杭州网络赛 划分树
- hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***
- HDU 4417 Super Mario(2012杭州网络赛 H 离线线段树)
- HDU 4417 Super Mario 第37届ACM/ICPC 杭州赛区网络赛1008题(树状数组或者线段树)
- HDU 4747 Mex (2013杭州网络赛1010题,线段树)★
- hdu 4738 Caocao's Bridges(2013杭州网络赛丶神坑)
- hdu 4279 Number 2012天津网络赛 数论 分析
- 2012 ACM/ICPC 杭州赛区网络赛Super Mario
- HDU4415 Assassin’s Creed 2012ACM/ICPC 杭州赛区网络赛 F
- hdu 4274 Spy's Work (2012 长春网络赛)
- hdu 4288 (成都赛区2012网络赛)
- 【Author : DS & MZ】 2012 ACM-ICPC 杭州网络预赛