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;
}