poj 2777 Count Color (线段树)

/*线段树染色,经典题,在这道题中学到了,只改变段,而没有下放到点,当下一次的
改变,须向下进行是,则要将父节点的颜色下方到子节点 

 vis[]用来标记 ,避免重复计算
*/

#include<stdio.h>
#include<string.h>
#define N 100010
struct node
{
    int b;
    int e;
    int c;
   

}p[N*4];
int sum,vis[N];
void build(int x,int l,int r)
{


        p[x].c=1;
        p[x].b=l;
        p[x].e=r;
        p[x].num=1;

        if(l==r)return ;

        int mid=(l+r)/2;
    build(x*2,l,mid);
    build(x*2+1,mid+1,r);

}
void change(int x,int l,int r,int color)
{
    if(p[x].c==color)return ;
    if(p[x].b==l&&p[x].e==r)
    {
        p[x].c=color;//只改变段

        return ;
    }
    if(p[x].c>=1)
    {
        p[x*2].c=p[x].c;//下放到子节点
        p[x*2+1].c=p[x].c;
        p[x].c=-1;
    }

    int mid=(p[x].b+p[x].e)/2;
    if(r<=mid)change(x*2,l,r,color);
    else
    {
        if(l>mid)change(x*2+1,l,r,color);
        else
        {
            change(x*2,l,mid,color);
            change(x*2+1,mid+1,r,color);
        }
    }





}
int Get(int x,int b,int e)
{

    if(p[x].c>=1)
    {
         if(!vis[p[x].c]){vis[p[x].c]=1;return 1;}
         else
        return 0;
    }
   int mid=(p[x].b+p[x].e)/2;
   if(e<=mid)
   {
          return Get(x*2,b,e);
   }
   else
   {
       if(b>mid)return Get(x*2+1,b,e);
       else
       {
           int n=Get(x*2,b,mid);
           int m=Get(x*2+1,mid+1,e);
           return m+n;

       }
   }

}
int main()
{
    int T;
    int L,O;
    while(scanf("%d%d%d",&L,&T,&O)!=EOF){

    build(1,1,L);
    getchar();
    char str[4];
    int b,e,c;
    sum=0;
    while(O--)
    {

        scanf("%s",str);
        if(str[0]=='C')
        {
            scanf("%d%d%d",&b,&e,&c);
            int t;
             if(b>e){t=b;b=e;e=t;}
            change(1,b,e,c);
        }
        else
        {
            scanf("%d%d",&b,&e);
             int t;
             if(b>e){t=b;b=e;e=t;}
            sum=0;
             for(int i=0;i<=T;i++)vis[i]=0;
           sum=Get(1,b,e);
            /*for(int i=1;i<=T;i++)
            {
                if(vis[i])sum++;
            }*/
            printf("%d\n",sum);
        }

    }
}



}

  

原文地址:https://www.cnblogs.com/acSzz/p/2444772.html