HDU 4419 Colourful Rectangle(线段树+扫描线)

题目链接

主要是pushup的代码,其他和区间更新+扫描线差不多。

那个区间如果要再刷一层x,那么sum[x][rt] = que[r+1] - que[l];但是如果原本有颜色为i,颜色将会变成i|x,sum[x][rt] 要减去以前的i颜色的部分。sum[i|x][rt]要加上那部分。

这个题还可以用容斥,容斥的话,多次求面积并就可以了,代码直接是模版,对扫描线,还是不熟啊。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <string>
  4 #include <algorithm>
  5 using namespace std;
  6 #define LL __int64
  7 #define maxn 20100
  8 #define lson l , m, rt<<1
  9 #define rson m+1, r,rt<<1|1
 10 int que[4*maxn];
 11 int sum[8][4*maxn];
 12 int cnt[4*maxn][4];
 13 LL ans[8];
 14 struct node
 15 {
 16     int lx,rx,y;
 17     int s;
 18     node() {}
 19     node (int a,int b,int c,int d):lx(a),rx(b),y(c),s(d) {}
 20     bool operator < (const node &S)const
 21     {
 22         return y < S.y;
 23     }
 24 } mat[2*maxn];
 25 int bin(int x,int n)
 26 {
 27     int str,end,mid;
 28     str = 0;
 29     end = n;
 30     while(str <= end)
 31     {
 32         mid = (str + end)/2;
 33         if(que[mid] == x)
 34             return mid;
 35         else if(que[mid] > x)
 36             end = mid - 1;
 37         else
 38             str = mid + 1;
 39     }
 40     return mid;
 41 }
 42 void pushup(int rt,int l,int r)
 43 {
 44     int i,x,t;
 45     x = 0;
 46     for(i = 1;i <= 3;i ++)
 47     {
 48         if(cnt[rt][i] > 0)
 49         x |= (1<<(i-1));
 50     }
 51     if(x)
 52     {
 53         for(i = 1;i < 8;i ++)
 54         sum[i][rt] = 0;
 55         sum[x][rt] = que[r+1] - que[l];
 56         for(i = 1; i < 8; i ++)//注意这里
 57         {
 58             if(x != (i|x))
 59             {
 60                 t = sum[i][rt<<1] + sum[i][rt<<1|1];
 61                 sum[x|i][rt] += t;
 62                 sum[x][rt] -= t;//减去原本的其他颜色
 63             }
 64         }
 65     }
 66     else if(l == r)
 67     {
 68         for(i = 1; i < 8; i ++)
 69             sum[i][rt] = 0;
 70     }
 71     else
 72     {
 73         for(i = 1; i < 8; i ++)
 74             sum[i][rt] = sum[i][rt<<1] + sum[i][rt<<1|1];
 75     }
 76 }
 77 void update(int L,int R,int c,int l,int r,int rt)
 78 {
 79     int m;
 80     if(l >= L&&r <= R)
 81     {
 82         c > 0 ? cnt[rt][c] ++:cnt[rt][-c] --;
 83         pushup(rt,l,r);
 84         return ;
 85     }
 86     m = (l+r)>>1;
 87     if(L <= m)
 88         update(L,R,c,lson);
 89     if(R > m)
 90         update(L,R,c,rson);
 91     pushup(rt,l,r);
 92 }
 93 int main()
 94 {
 95     int n,cas = 1,i,j,l,r,t,num;
 96     char ch[10];
 97     int a,b,c,d,col;
 98     scanf("%d",&t);
 99     while(t --)
100     {
101         scanf("%d",&n);
102         num = 0;
103         for(i = 1; i <= n; i ++)
104         {
105             scanf("%s%d%d%d%d",ch,&a,&b,&c,&d);
106             if(ch[0] == 'R')
107                 col = 1;
108             else if(ch[0] == 'G')
109                 col = 2;
110             else
111                 col = 3;
112             mat[num] = node(a,c,b,col);
113             que[num++] = a;
114             mat[num] = node(a,c,d,-col);
115             que[num++] = c;
116         }
117         sort(que,que+num);
118         sort(mat,mat+num);
119         int k = 1;
120         for(i = 1; i < num; i ++)
121         {
122             if(que[i] != que[i-1])
123                 que[k++] = que[i];
124         }
125         memset(cnt,0,sizeof(cnt));
126         memset(sum,0,sizeof(sum));
127         memset(ans,0,sizeof(ans));
128         for(i = 0; i < num-1; i ++)
129         {
130             l = bin(mat[i].lx,k-1);
131             r = bin(mat[i].rx,k-1) - 1;
132             if(l <= r)
133                 update(l,r,mat[i].s,0,k-1,1);
134             for(j = 1; j < 8; j ++)
135                 ans[j] += ((LL)mat[i+1].y - (LL)mat[i].y)*(LL)sum[j][1];
136         }
137         printf("Case %d:\n",cas++);
138         printf("%I64d\n",ans[1]);
139         printf("%I64d\n",ans[2]);
140         printf("%I64d\n",ans[4]);
141         printf("%I64d\n",ans[3]);
142         printf("%I64d\n",ans[5]);
143         printf("%I64d\n",ans[6]);
144         printf("%I64d\n",ans[7]);
145     }
146     return 0;
147 }

 

posted @ 2013-08-06 10:26  Naix_x  阅读(271)  评论(0编辑  收藏  举报