POJ2777 Count Color
原题链接:http://poj.org/problem?id=2777
水线段树,打上lazy标志,节点保存区间颜色值,如果区间颜色有多种,那么保存值为 -1。
记录颜色数的时候一定要用位运算,再不济也用个数组哈希一下。(而我一开始用STL的set,神啊,TLE了一下午啊!还以为是写线段树出的问题,没想到STL这时候慢的一逼啊!恰巧POJ的C++编译器挂了!用G++交就更慢了!慢了慢了就TLE了!)
View Code
1 #include <stdio.h> 2 #include <string.h> 3 #define lson cur << 1, l, mid 4 #define rson cur << 1 | 1, mid + 1, r 5 #define N 100005 6 7 int tree[N << 2], lazy[N << 2], ans; 8 9 void swap(int &a, int &b) 10 { 11 int c = a; 12 a = b; 13 b = c; 14 } 15 16 void pushdown(int cur) 17 { 18 if(lazy[cur] != -1) 19 { 20 tree[cur << 1] = tree[cur << 1 | 1] = lazy[cur]; 21 lazy[cur << 1] = lazy[cur << 1 | 1] = lazy[cur]; 22 lazy[cur] = -1; 23 } 24 } 25 26 void pushup(int cur) 27 { 28 if(tree[cur << 1] == -1 || tree[cur << 1 | 1] == -1 || tree[cur << 1] != tree[cur << 1 | 1]) 29 tree[cur] = -1; 30 else 31 tree[cur] = tree[cur << 1]; 32 } 33 34 void update(int cur, int l, int r, int s, int t, int color) 35 { 36 if(l >= s && r <= t) 37 { 38 lazy[cur] = color; 39 tree[cur] = color; 40 return ; 41 } 42 pushdown(cur); 43 int mid = (l + r) >> 1; 44 if(mid >= s) 45 update(lson, s, t, color); 46 if(mid + 1 <= t) 47 update(rson, s, t, color); 48 pushup(cur); 49 } 50 51 void query(int cur, int l, int r, int s, int t) 52 { 53 if(lazy[cur] != -1) 54 { 55 ans = ans | (1 << lazy[cur]); 56 return ; 57 } 58 if(tree[cur] != -1) 59 { 60 ans = ans | (1 << tree[cur]); 61 return ; 62 } 63 pushdown(cur); 64 int mid = (l + r) >> 1; 65 if(mid >= s) 66 query(lson, s, t); 67 if(mid + 1 <= t) 68 query(rson, s, t); 69 } 70 71 void build(int cur, int l, int r) 72 { 73 tree[cur] = 1; 74 lazy[cur] = -1; 75 if(l == r) 76 return ; 77 int mid = (l + r) >> 1; 78 build(lson); 79 build(rson); 80 } 81 82 int main() 83 { 84 int l, t, o, a, b, c, cnt, i; 85 char op[3]; 86 while(scanf("%d%d%d", &l, &t, &o) != EOF) 87 { 88 build(1, 1, l); 89 while(o --) 90 { 91 scanf("%s", op); 92 if(op[0] == 'C') 93 { 94 scanf("%d%d%d", &a, &b, &c); 95 if(a > b) swap(a, b); 96 update(1, 1, l, a, b, c); 97 } 98 else if(op[0] == 'P') 99 { 100 scanf("%d%d", &a, &b); 101 ans = 0; 102 if(a > b) swap(a, b); 103 query(1, 1, l, a, b); 104 for(cnt = i = 0; i <= 30; i ++) 105 if((ans >> i) & 1) 106 cnt ++; 107 printf("%d\n", cnt); 108 } 109 } 110 } 111 return 0; 112 }