• 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);
            }
    
        }
    }
    
    
    
    }
    

      

  • 相关阅读:
    js插件-图片椭圆轮播效果
    js-放大镜效果
    vue使用技巧,及遇到的问题
    vue的传参方式和router使用技巧
    关于new Date()的日期格式处理
    图片上传预览
    缓动动画的原理
    input不能输入汉字和负数
    上传格式判断方法
    Vue-cli3.0配置全局less
  • 原文地址:https://www.cnblogs.com/acSzz/p/2444772.html
Copyright © 2020-2023  润新知