• 2020ccpc绵阳 J题 区间染色


    cf终于有题面传送门,把能补的都补了吧

    题面

    给n个点长度为t,亮度为x的长灯,铺在长度为m 的路上,每(0~t)* k(k=0,2,4……)的位置铺灯,问最好路的亮度情况。

    样例

     2 8
     1 1
     2 2
    

    输出

    2 2 1 0 2 2 1 0

    思路

    并查集染色问题。先对灯种类离散化,找到每个t的最大值x,然后按照x的大小从大到小排序

    循环区间(0~t)* k(k=0,2,4……)把每个点并到(0~t)* k + 1

    代码

    #include<bits/stdc++.h>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define lson(x) x<<1
    #define rson(x) x<<1|1
    using namespace std;
    const int N=1e5+10;
    struct node{
        int t,x;
        friend bool operator<(const node a,const node b){
            if(a.x==b.x){
                return a.t<b.t;
            }
            return a.x>b.x;
        }
    }a[N];
    int liang[N];
    int f[N];
    int F(int x){
        return f[x]==x?x:f[x]=F(f[x]);
    }
    void mere(int x,int y){
        int xx=F(x),yy=F(y);
        if(xx!=yy){
            f[xx]=f[yy];
        }
    }
    inline int read(){
        char c;
        int ret=0;
        while((c=getchar())<'0' || c>'9');
        while(c>='0' && c<='9'){
            ret=ret*10+(c-'0'),c=getchar();
        }
        return ret;
    }
    int main(){
        int T,ca=1;
        scanf("%d",&T);
        while(T--){
            int n,m;
            scanf("%d%d",&n,&m);
           // n=read();m=read();
            map<int,int>mp;
            int cnt=1;
            for(int i=1;i<=m+1;i++){
                liang[i]=0;f[i]=i;
            }
            for(int i=0;i<n;i++){
                int t,x;
                scanf("%d%d",&t,&x);
               // t=read();x=read();
                if(mp[t]==0){
                    mp[t]=cnt++;
                    a[mp[t]].t=t;a[mp[t]].x=x;
                }
                else{
                   a[mp[t]].x=max(a[mp[t]].x,x);
                }
            }
            sort(a+1,a+cnt);
            for(int i=1;i<cnt;i++){
                int t=a[i].t,x=a[i].x;
                for(int j=1;j<=m;j+=2*t){
                    //cout<<j<<endl;
                    int l=F(j),r=min(j+t-1,m);
                    while(l<=r){
                        liang[l]=x;
                        mere(l,r+1);
                        l=F(l+1);
                    }
                }
                if(F(1)==m+1){break;}
            }
            printf("Case #%d: ",ca++);
            for(int i=1;i<=m;i++){
                printf(i==m?"%d
    ":"%d ",liang[i]);
            }
        }
        return 0;
    }
    
    

    ccpc为什么现在题目这么难,直接暴露了,我数据结构和博弈垃圾成fw,学了图论什么都没用。。水哥线段树写出了,到时候把线段树的写法学一下

  • 相关阅读:
    sql server 辅助工具
    visual studio 辅助工具
    c# socket 判断端口是否被占用
    Socket 学习(三).1 tcp 通讯
    Socket 学习(三)
    c# 文件同步服务器,iis 集群 ,代码同步(二)
    免费3节精彩课程
    c# p2p 穿透(源码加密)
    互联网点对点通讯(P2P)
    文件同步服务器,iis 集群 ,代码同步(一)
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/13910997.html
Copyright © 2020-2023  润新知