标签:
题目链接:http://poj.org/problem?id=2777
Description
Input
Output
Sample Input
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Output
2 1
Source
题意:
给一个固定长度为L的画板
有两个操作:
C A B C:区间A--B内涂上颜色C。
P A B:查询区间AB内颜色种类数。
PS:此题和HDU:5023是类似的!
附题解:http://blog.csdn.net/u012860063/article/details/39434665
代码例如以下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l , mid , rt << 1
#define rson mid + 1 , r , rt << 1 | 1
#define LL int
const int maxn = 110017;
LL add[maxn<<2];
LL sum[maxn<<2];
void PushUp(int rt)
{
    //把当前结点的信息更新到父结点
    sum[rt] = sum[rt<<1] | sum[rt<<1|1];//总共的颜色
}
void PushDown(int rt,int m)
{
    if(add[rt])
    {
        add[rt<<1] = add[rt];
        add[rt<<1|1] = add[rt];
        sum[rt<<1] = add[rt];
        sum[rt<<1|1] = add[rt];
        add[rt] = 0;//将标记向儿子节点移动后,父节点的延迟标记去掉
        //传递后,当前节点标记域清空
    }
}
void build(int l,int r,int rt)
{
    add[rt] = 0;//初始化为全部结点未被标记
    if (l == r)
    {
        sum[rt] = 1;//初始颜色为1
        return ;
    }
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if (L <= l && r <= R)
    {
        add[rt] =1<<(c-1);//位运算左移表示有某种颜色
        sum[rt] =1<<(c-1);
        return ;
    }
    PushDown(rt , r - l + 1);//----延迟标志域向下传递
    int mid = (l + r) >> 1;
    if (L <= mid)
        update(L , R , c , lson);//更新左儿子
    if (mid < R)
        update(L , R , c , rson);//更新右儿子
    PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
    if (L <= l && r <= R)
    {
        return sum[rt];
    }
    //要取rt子节点的值时,也要先把rt的延迟标记向下移动
    PushDown(rt , r - l + 1);
    int mid = (l + r) >> 1;
    LL ret = 0;
    if (L <= mid)
        ret |= query(L , R , lson);
    if (mid < R)
        ret |= query(L , R , rson);
    return ret;
}
int main()
{
    int L, T, O;
    int a, b, c;
    while(~scanf("%d%d%d",&L,&T,&O))
    {
        build(1, L, 1);//建树
        while(O--)//Q为询问次数
        {
            char op[2];
            scanf("%s",op);
            if(op[0] == 'P')
            {
                scanf("%d%d",&a,&b);
                if(a > b)
                {
                    int t = a;
                    a = b;
                    b = t;
                }
                LL tt=query(a, b, 1, L, 1);
                int ans = 0;
                while(tt)
                {
                    if(tt&1)
                    {
                        ans++;
                    }
                    tt>>=1;
                }
                printf("%d\n",ans);
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c);
                if(a > b)
                {
                    int t = a;
                    a = b;
                    b = t;
                }
                update(a, b, c, 1, L, 1);
            }
        }
    }
    return 0;
}
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/4304718.html