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 }