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 }

 

你可能感兴趣的:(HDU)