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;
    }
    
  • 相关阅读:
    Redis连接池的介绍和原理
    Golang操作第三方开源Redis库
    Redis的五大数据类型和CRUD操作
    Redis的基本使用
    Redis数据库的基本介绍和安装
    Golang基于TCP协议实现简单的server和client聊天
    Golang反射中的Type和Kind的区别
    Golang中的常量
    Golang对基本数据类型和结构体进行反射
    Vue 使用lodash库减少watch对后台请求压力
  • 原文地址:https://www.cnblogs.com/minun/p/10473773.html
Copyright © 2011-2022 走看看