首页 > 代码库 > poj 2777 Count Color(线段树区间修改)

poj 2777 Count Color(线段树区间修改)

题目链接:http://poj.org/problem?id=2777

题目意思:就是问你在询问的区间里有几种不同的颜色

思路:这题和一般的区间修改差不多,但是唯一不同的就是我们要怎么计算有种颜色,所以这时候我们就需要把延时标记赋予不同的意义,当某段区间有多种颜色时就赋值为-1,当为一种颜色时就把它赋值为这个颜色的号数。这儿我们要怎么统计询问区间不同的颜色数叻,为了不重复计算同一种颜色,那么我们就需要用一个数组来标记计算过的颜色,当我们下次遇到时就不需要再次计算了。。。。

代码核心处就在计数那儿。。。。其它部分都是模板。。。。。。



code:

<span style="font-size:18px;">#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define L(u) u<<1
#define R(u) u<<1|1
using namespace std;

const int MAXN=100100;
bool vis[35];
int cnt;

struct Node
{
    int l,r;
    int color;
}node[MAXN*4];

void build(int u,int l,int r)          //建树
{
    node[u].l=l;
    node[u].r=r;
    node[u].color=1;
    if(l==r)
    {
        return ;
    }
    int m=(l+r)/2;
    build(L(u),l,m);
    build(R(u),m+1,r);
}

void pushdown(int u)
{
    if(node[u].color>0)
    {
        node[L(u)].color=node[R(u)].color=node[u].color;
    }
}

void pushup(int u)
{
    if(node[L(u)].color==node[R(u)].color)
    {
        node[u].color=node[L(u)].color;
    }
    else
    {
        node[u].color=-1;
    }
}

void update(int l,int r,int v,int u)
{
    if(l<=node[u].l&&node[u].r<=r)
    {
        node[u].color=v;
        return;
    }
    pushdown(u);
    int m=(node[u].l+node[u].r)/2;
    //if(l<=m) update(l,r,v,L(u));
    //if(m<r)  update(l,r,v,R(u));
    if(r<=m) update(l,r,v,L(u));
    else if(l>m) update(l,r,v,R(u));
    else
    {
        update(l,m,v,L(u));
        update(m+1,r,v,R(u));
    }
    pushup(u);
}

void query(int l,int r,int u)
{
    if(node[u].color>0)          //为同一种颜色
    {
        if(vis[node[u].color]==false)      //这种颜色没有计算过  
        {
            cnt++;
        }
        vis[node[u].color]=true;           //标记为计算过的
        return ;
    }

    int m=(node[u].l+node[u].r)/2;
    //if(l<=m) query(l,r,L(u));
    //if(m<r)  query(l,r,R(u));
    if(r<=m) query(l,r,L(u));
    else if(l>m) query(l,r,R(u));
    else
    {
        query(l,m,L(u));
        query(m+1,r,R(u));
    }
}

int main()
{
    int n,t,q;
    while(scanf("%d%d%d",&n,&t,&q)==3)
    {
        build(1,1,n);
        while(q--)
        {
            char str[10];
            scanf("%s",str);
            if(str[0]=='C')
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                update(x,y,z,1);
            }
            else
            {
                int x,y;
                scanf("%d%d",&x,&y);
                memset(vis,0,sizeof(vis));
                cnt=0;
                query(x,y,1);
                printf("%d\n",cnt);
            }
        }
    }
    return 0;
}
</span>