http://poj.org/problem?id=2777
http://acm.zstu.edu.cn:8080/JudgeOnline/showproblem?problem_id=3109
(1)给指定的区间重新染色、统计不同颜色数。难点在于如何有效地重新染色。这里用到了 pushdown() 函数,即不在本次全部更新,而是设置标志数组
(color[]),在下次要访问的时候加上 pushdown() 函数。(要更新,下次,而且用到了才更新。)
(2)有一个细节,输入的 a, b 需要预处理 if(a>b) {int x=a;a=b;b=x;} (否则,必然会WA。。)
具体代码:
View Code 
#include<stdio.h> #include<algorithm> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; const int N=101000<<2; int n, t, m; int color[N], num[N]; void pushup(int rt) { num[rt]=num[rt<<1]|num[rt<<1|1]; } void pushdown(int rt) { if(color[rt]) { color[rt<<1]=color[rt<<1|1]=1; num[rt<<1]=num[rt<<1|1]=num[rt]; color[rt]=0; } } int query(int L, int R, int l, int r, int rt) { if(L<=l&&r<=R) { return num[rt]; } pushdown(rt); int m=(l+r)>>1; int ret=0; if(L<=m) ret=ret|query(L, R, lson); if(R>m) ret=ret|query(L, R, rson); return ret; } void update(int L, int R, int ne, int l, int r, int rt) { if(L<=l&&r<=R) { color[rt]=1; num[rt]=1<<(ne-1); return ; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L, R, ne, lson); if(R>m) update(L, R, ne, rson); pushup(rt); } int main() { int i, j; while(scanf("%d%d%d", &n, &t, &m)!=EOF) { num[1]=color[1]=1; for(i=1;i<=m;i++) { char ch; int a, b, c; scanf(" %c", &ch); if(ch=='C') { scanf("%d%d%d", &a, &b, &c); if(a>b) {int x=a;a=b;b=x;} update(a, b, c, 1, n, 1); } else if(ch=='P') { scanf("%d%d", &a, &b); if(a>b) {int x=a;a=b;b=x;} int x=query(a, b, 1, n, 1); int count=0; for(j=0;j<t;j++) if(x&(1<<j)) count++; printf("%d\n", count); } } } return 0; }
                    
                
