POJ 2777 Count Color(线段树!!!)

http://poj.org/problem?id=2777

题意:给出一段区间 L ,T种颜色,O种操作(1 <= L <= 100000), T(1 <= T <= 30) , (1 <= O <= 100000). ,初始时颜色都是染第一种颜色,然后再修改一些区间的颜色,给出一段区间,问这段区间内有多少种颜色。

1 .线段树的一个很重要的部分就是节点存的内容,除了l,r,c外还有一个state(该段区间有多少种颜色),开始没state还超时了,加了一个剪枝勉强过,可是30种染色,用二进制存的话,效率很高,所以改成了二进制

2. 更新时的下传和上传,very重要

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define nMAX 100100
using namespace std;
struct Node
{
    int l,r,c,state;
}node[nMAX*4];
int L,T;
void create(int l,int r,int u)
{
    node[u].l=l,node[u].r=r,node[u].state=1,node[u].c=0;//初始化为0
    if(l==r)return ;
    int mid=(l+r)/2;
    create(l,mid,2*u);
    create(mid+1,r,2*u+1);
}
void printColor(int l,int r,int c,int u)
{
    if(node[u].l>=l&&node[u].r<=r)
      {node[u].c=c; node[u].state=1<<(c-1); return;}

    if(node[u].c)//下传
    {
        node[2*u].c=node[u].c,node[2*u+1].c=node[u].c;
        node[2*u].state=node[u].state,
        node[2*u+1].state=node[u].state,
        node[u].c=0;
    }
    int mid=(node[u].l+node[u].r)/2;
    if(r<=mid) printColor(l,r,c,2*u);
    else if(l>mid) printColor(l,r,c,2*u+1);
    else
    {
        printColor(l,mid,c,2*u);
        printColor(mid+1,r,c,2*u+1);
    }
    node[u].state=node[2*u].state|node[2*u+1].state;//上传
}

int calculate(int l,int r,int u)
{
    if(node[u].l>=l&&node[u].r<=r)
        return node[u].state;
    if(node[u].c)//下传
    {
        node[2*u].c=node[u].c, node[2*u+1].c=node[u].c;
        node[2*u].state=node[u].state,
        node[2*u+1].state=node[u].state,
        node[u].c=0;
    }
    int mid=(node[u].l+node[u].r)/2;
    if(r<=mid) {return calculate(l,r,2*u);}
    else if(l>mid) {return calculate(l,r,2*u+1);}
    else
       return  calculate(l,mid,2*u)|calculate(mid+1,r,2*u+1);
}
int Binary(int u)
{
    int ans=0;
    while(u>0)
    {
        if(u%2)ans++;
        u/=2;
    }
    return ans;
}
int main()
{
    int i,j,k,O;
    char ch;
    while(~scanf("%d%d%d",&L,&T,&O))
    {
        create(1,L,1);
        int cnt=1;
        while(O--)
        {
            getchar();
            scanf("%c",&ch);
            if(ch=='C')
            {
                scanf("%d%d%d",&i,&j,&k);
                int t;
                if(i>j){t=i,i=j,j=t;}
                printColor(i,j,k,1);
            }
            else
            {
                scanf("%d%d",&i,&j);
                int t;
                if(i>j){t=i,i=j,j=t;}
                int ans=calculate(i,j,1);
                ans=Binary(ans);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}

  

posted @ 2012-08-20 21:28  快乐.  阅读(133)  评论(0编辑  收藏  举报