hdu 4419 矩形面积覆盖颜色

一开始接触到这道题目的时候就有了思路,应该是之前做线段树出来的结果吧,不过这个更新真的想了很久。

把其中的红、绿、蓝以1、2、4来代替,那么通过位运算就能将其他的颜色状态都演化出来。

代码部分就更新部分最精华,这还是参考的网上的某位大哥的神作而得来的。。

View Code
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<string.h>
  5 #include<stdlib.h>
  6 #define LL __int64
  7 using std::sort;
  8 using std::unique;
  9 using std::swap;
 10 const int N = 10002;
 11 struct Line
 12 {
 13        int y,x1,x2;
 14        int flag;
 15        bool operator < (const Line & tmp)const
 16        {
 17            return y<tmp.y;
 18        }
 19 }L[N<<1];
 20 LL sum[N<<3][8],ans[8],cover[N<<3][5];
 21 int X[N<<1];
 22 int Fin(int k,int len)
 23 {
 24     int l=0,r=len;
 25     while(l<r)
 26     {
 27          int m=(l+r)>>1;
 28          if(X[m]==k)return m;
 29          if(X[m]>k)r=m-1;
 30          else l=m+1;
 31     }
 32     return l;
 33 }
 34 void PushUp(int t,int l,int r)
 35 {
 36       int state=((cover[t][1]>0?1:0)|(cover[t][2]>0?2:0)|(cover[t][4]>0?4:0));
 37       int t1=t<<1,t2=t1|1;
 38       if(state)
 39       {
 40           for(int i=1;i<=7;i++)sum[t][i]=0;
 41           sum[t][state]=X[r+1]-X[l];
 42           for(int i=1;i<=7;i++)
 43           {
 44               if(state!=(state|i))
 45               {
 46                   int add=sum[t1][i]+sum[t2][i];
 47                   sum[t][state|i]+=add;
 48                   sum[t][state]-=add;
 49               }
 50           }
 51       }
 52       else
 53         if(l!=r)
 54         for(int i=1;i<=7;i++)sum[t][i]=sum[t1][i]+sum[t2][i];
 55         else
 56         for(int i=1;i<=7;i++)sum[t][i]=0;
 57 }
 58 void update(int t,int l,int r,int L,int R,int val)
 59 {
 60      if(L<=l&&r<=R)
 61      {
 62         val>=0?(cover[t][val]++):(cover[t][-val]--);
 63         PushUp(t,l,r);
 64         return ;
 65      }
 66      int m=(l+r)>>1;
 67      if(L<=m)update(t<<1,l,m,L,R,val);
 68      if(R>m)update(t<<1|1,m+1,r,L,R,val);
 69      PushUp(t,l,r);
 70 }
 71 int main()
 72 {
 73     int n,x1,x2,y1,y2,T=0,t;
 74     char temp[5];
 75     scanf("%d",&t);
 76     while(t--)
 77     {
 78           scanf("%d",&n);
 79           int topx=0,topl=0;
 80           for(int i=0;i<n;i++)
 81           {
 82               scanf("%s",temp);
 83               scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
 84               switch(temp[0])
 85               {
 86                   case 'R':L[topl].flag=1,L[topl+1].flag=-1;break;
 87                   case 'G':L[topl].flag=2,L[topl+1].flag=-2;break;
 88                   case 'B':L[topl].flag=4;L[topl+1].flag=-4;break;
 89                   default:break;
 90               }
 91               L[topl].x1=x1,L[topl].x2=x2,L[topl].y=y1;topl++;
 92               L[topl].x1=x1,L[topl].x2=x2,L[topl].y=y2;topl++;
 93               X[topx++]=x1;
 94               X[topx++]=x2;
 95           }
 96           sort(X,X+topx);
 97           topx=unique(X,X+topx)-X-1;
 98           sort(L,L+topl);
 99           memset(sum,0,sizeof(sum));
100           memset(ans,0,sizeof(ans));
101           memset(cover,0,sizeof(cover));
102           for(int i=0;i<topl-1;i++)
103           {
104               int l=Fin(L[i].x1,topx);
105               int r=Fin(L[i].x2,topx)-1;
106               if(l<=r)update(1,0,topx,l,r,L[i].flag);
107               for(int j=1;j<=7;j++)
108                   if(L[i+1].y-L[i].y!=0)
109                   ans[j]+=sum[1][j]*(LL)(L[i+1].y-L[i].y);
110           }
111           swap(ans[3],ans[4]);
112           printf("Case %d:\n",++T);
113           for(int i=1;i<=7;i++)printf("%I64d\n",ans[i]);
114     }
115     return 0;
116 }

 

posted @ 2012-11-24 11:25  诺小J  阅读(231)  评论(0编辑  收藏  举报