zoukankan      html  css  js  c++  java
  • ZOJ 1606 Count the Colors (线段数染色)

    题目大意:

    给你一段长度为 8000 的绳子,n 次操作,每次将[ l  r ]区间染色为 c ,染色会覆盖掉之前的染色,所有数字不超过8000,统计最后的颜色和出现的不连续区间的个数。按颜色顺序输出。

     题解思路:

    线段数区间染色,因为是区间染色,所以在每个2点之间又加了一个点来代表此区间的颜色。

    最后统计区间个数用一个last标记一下上次的颜色即可,注意如果颜色断掉last要初始一下。

    (这个数据范围,暴力不好吗)

    几个样例

    2

    1 2 1

    3 4 1

    3

    1 10 0

    1 4  1

    5 10 2

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    
    const int maxn=16005;
    
    using namespace std;
    
    int col[4*maxn],n,cnt[maxn],last;
    
    void built(int l,int r,int now)//初始化
    {
        int mid=(l+r)/2;
        col[now]=-1;
        if(l==r) return ;
        built(l,mid,now*2);
        built(mid+1,r,now*2+1);
    }
    
    void updata(int l,int r,int left,int right, int c,int now)
    {
        int mid=(l+r)/2;
        if(left<=l&&r<=right)
        {
            col[now]=c;
            return ;
        }
        if(l==r) return ;
        if(col[now]!=-1)//向下传递
        {
            col[now*2]=col[now*2+1]=col[now];
            col[now]=-1;
        }
        if(left<=mid) updata(l,mid,left,right,c,now*2);
        if(right>mid) updata(mid+1,r,left,right,c,now*2+1);
    }
    
    void query(int l,int r,int now)
    {
        int mid=(l+r)/2;
        if(col[now]!=-1)
        {
            if(col[now]!=last)
            {
                cnt[col[now]]++;
                last=col[now];
            }
            return ;
        }
        if(l==r) {last=-1;return ;}//如果到了叶子节点且没有颜色,表示颜色断掉
        query(l,mid,now*2);
        query(mid+1,r,now*2+1);
    }
    
    int main(){
        while(~scanf("%d",&n))
        {
            built(0,16000,1);
            for(int i=1;i<=n;i++)
            {
                int l,r,k;
                scanf("%d%d%d",&l,&r,&k);
                updata(0,16000,2*l,2*r,k,1);//区间加点,直接*2处理了
            }
            last=-1;
            memset(cnt,0,sizeof(cnt));
            query(0,16000,1);
            for(int i=0;i<=8000;i++)
            {
                if(cnt[i]!=0)
                {
                    printf("%d %d
    ",i,cnt[i]);
                }
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    ORACLE--Connect By、Level、Start With的使用(Hierarchical query-层次查询)
    小工具-ANT
    测试类。。。重写篇
    java代码----求最大值,平均值。。。
    java代码,输入n多个数,求其平均值,虽有重复,但是第二次,我就乱写了
    java代码求输入数的平均值~~~~
    java代码求输入的三个数的最大值
    java代码switch语句求分数等级
    java代码求分数等级的输出~~~
    java代码 求和1+1/2+1/3+1/4+1/5+1/6+.......+1/n 的值~~~~
  • 原文地址:https://www.cnblogs.com/minun/p/10473773.html
Copyright © 2011-2022 走看看