POJ2777 - Count Color(区间修改&&懒惰标记&&位运算)

题目大意

给定一个长度为n的序列A,可以对其进行以下两种操作:

1、“C A B C”把区间[A,B]的值全部修改为C

2、“P A B”查询在区间[A,B]中不同的元素总数

题解

每一种颜色的数值用一个2的幂来表示,父节点的值刚好是两个子节点的并操作,答案就是查询的区间值转换成二进制后1的个数,尼玛调试了好久。。被懒惰标记坑了。。。在查询的时候还需要进行更新。。。因为用了懒惰标记,查询的时候有些结点还没有进行更新。。。。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100005
#define lson l , m , s << 1
#define rson m+1 , r , s << 1 | 1
using namespace std;
int sumv[MAXN<<2],setv[MAXN<<2];
void PushUp(int s)
{
    sumv[s]=sumv[s<<1]|sumv[s<<1|1];
}
void PushDown(int s)
{
    if(setv[s])
    {
        setv[s<<1]=setv[s<<1|1]=setv[s];
        sumv[s<<1]=1<<(setv[s]-1);
        sumv[s<<1|1]=1<<(setv[s]-1);
        setv[s]=0;
    }
}
void build(int l,int r,int s)
{
    sumv[s]=1;
    setv[s]=0;
    if(l==r) return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
void update(int ql,int qr,int d,int l,int r,int s)
{
    if(ql<=l&&r<=qr)
    {
        sumv[s]=1<<(d-1);
        setv[s]=d;
        return;
    }
    PushDown(s);
    int m=(l+r)>>1;
    if(ql<=m) update(ql,qr,d,lson);
    if(qr>m) update(ql,qr,d,rson);
    PushUp(s);
}
int query(int ql,int qr,int l,int r,int s)
{
    if((ql<=l&&r<=qr)||setv[s])
        return sumv[s];
    int m=(l+r)>>1,ans=0;
    if(ql<=m) ans=ans|query(ql,qr,lson);
    if(qr>m) ans=ans|query(ql,qr,rson);
    return ans;
}
int main(void)
{
    int L,T,p,a,b,c;
    char ch[5];
    while(scanf("%d%d%d",&L,&T,&p)!=EOF)
    {
        build(1,L,1);
        while(p--)
        {
            scanf("%s",ch);
            if(ch[0]=='C')
            {
                scanf("%d%d%d",&a,&b,&c);
                update(a,b,c,1,L,1);
            }
            else
            {
                scanf("%d%d",&a,&b);
                int t=query(a,b,1,L,1);
                int sum=0;
                while(t)
                {
                    sum+=(t&1);
                   t=(t>>1);
                }
                printf("%d\n",sum);
            }
        }
    }
    return 0;
}

posted on 2013-05-13 23:02  仗剑奔走天涯  阅读(243)  评论(0编辑  收藏  举报

导航