• Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) D. Array Restoration


    D. Array Restoration
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Initially there was an array aa consisting of nn integers. Positions in it are numbered from 11 to nn.

    Exactly qq queries were performed on the array. During the ii-th query some segment (li,ri)(li,ri) (1lirin)(1≤li≤ri≤n) was selected and values of elements on positions from lili to riri inclusive got changed to ii. The order of the queries couldn't be changed and all qq queries were applied. It is also known that every position from 11 to nn got covered by at least one segment.

    We could have offered you the problem about checking if some given array (consisting of nn integers with values from 11 to qq) can be obtained by the aforementioned queries. However, we decided that it will come too easy for you.

    So the enhancement we introduced to it is the following. Some set of positions (possibly empty) in this array is selected and values of elements on these positions are set to 00.

    Your task is to check if this array can be obtained by the aforementioned queries. Also if it can be obtained then restore this array.

    If there are multiple possible arrays then print any of them.

    Input

    The first line contains two integers nn and qq (1n,q21051≤n,q≤2⋅105) — the number of elements of the array and the number of queries perfomed on it.

    The second line contains nn integer numbers a1,a2,,ana1,a2,…,an (0aiq0≤ai≤q) — the resulting array. If element at some position jj is equal to 00then the value of element at this position can be any integer from 11 to qq.

    Output

    Print "YES" if the array aa can be obtained by performing qq queries. Segments (li,ri)(li,ri) (1lirin)(1≤li≤ri≤n) are chosen separately for each query. Every position from 11 to nn should be covered by at least one segment.

    Otherwise print "NO".

    If some array can be obtained then print nn integers on the second line — the ii-th number should be equal to the ii-th element of the resulting array and should have value from 11 to qq. This array should be obtainable by performing exactly qq queries.

    If there are multiple possible arrays then print any of them.

    Examples
    input
    Copy
    4 3
    1 0 2 3
    output
    Copy
    YES
    1 2 2 3
    input
    Copy
    3 10
    10 10 10
    output
    Copy
    YES
    10 10 10
    input
    Copy
    5 6
    6 5 6 2 2
    output
    Copy
    NO
    input
    Copy
    3 5
    0 0 0
    output
    Copy
    YES
    5 4 2
    Note

    In the first example you can also replace 00 with 11 but not with 33.

    In the second example it doesn't really matter what segments to choose until query 1010 when the segment is (1,3)(1,3).

    The third example showcases the fact that the order of queries can't be changed, you can't firstly set (1,3)(1,3) to 66 and after that change (2,2)(2,2) to 55. The segment of 55 should be applied before segment of 66.

    There is a lot of correct resulting arrays for the fourth example.

    题意:起初我们有一个n个数的排列,然后我们随机让一些数变成了0,这些数的范围都是1-q,然后让我们求原来这个排列,他的排列求来的方法是染色,它总共有i次染色,每次

    染色一个区间,让这个区间的数都变成i

     

    思路:我们第i次染色会让这个区间的数都变成i,然后我们仔细想想,相同的数是连续的,如果不是连续的,肯定是后面再次在他们中间染了色,所以有规律

    两个相同 的数中间肯定都是比它大的数不然就是错的,然后我们可以判断这一段的区间最小值是不是等于它就好,用线段树维护区间最小值,然后我们再来解决0的问题

    因为他是随机让一些数变成的0,所以我们可以让0变成1-q中间的任意一个数,很容易发现,我们把0变成两边的一个数就行,就不要在意相同数区间有比他小的数

    我们还要注意,因为我们是按顺序染色,所以最后我们肯定有一个数q,最后一次染色留下来的,如果没有这个数,我们要把其中一个0变成q,如果也没有那就直接判断错

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct sss
    {
        int left;
        int right;
        int mn;
    }a[200001*4];
    int n,m;
    int c[200001];
    int f[200001];
    void build(int cnt,int left,int right)
    {
        a[cnt].left=left;
        a[cnt].right=right;
        if(left==right)
        {
            a[cnt].mn=c[left];
            return;
        }
        int mid=(left+right)/2;
        build(cnt*2,left,mid);
        build(cnt*2+1,mid+1,right);
        a[cnt].mn=min(a[cnt*2].mn,a[cnt*2+1].mn);
    }
    int updata(int cnt,int left,int right)
    {
        if(left<=a[cnt].left&&right>=a[cnt].right)
        {
            return a[cnt].mn;
        }
        int mid=(a[cnt].left+a[cnt].right)/2;
        if(mid>=right) return updata(cnt*2,left,right);
        else if(left>mid) return updata(cnt*2+1,left,right);
        else{
            return min(updata(cnt*2,left,mid),updata(cnt*2+1,mid+1,right));
        } 
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int flag1=0,flag2=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&c[i]);
            if(c[i]==m) flag1=1;
            if(c[i]==0) flag2=1;
        }
        if(flag1==0&&flag2==0)
        {
            printf("NO");
            return 0;
        }
        if(flag1==0)
        {
            for(int i=1;i<=n;i++)
            {
                if(c[i]==0)
                {
                    c[i]=m;
                    break;
                }
            }
        }
        int ans=1;
        for(int i=1;i<=n;i++)
        {
            if(c[i]==0) c[i]=ans;
            else ans=c[i];
        }
        build(1,1,n);
        for(int i=1;i<=n;i++)
        {
            if(f[c[i]]==0) f[c[i]]=i;
            else{
                if(updata(1,f[c[i]],i)==c[i])
                {
                    f[c[i]]=i;
                     continue;
                }
                printf("NO");
                return 0;
            }
        }
        printf("YES
    ");
        for(int i=1;i<=n;i++)
        {
            if(i==1) printf("%d",c[i]);
            else printf(" %d",c[i]);
        }
    }
  • 相关阅读:
    asp.net mvc实现图片下载防盗链及提示是否存在!
    Asp.net mvc + Javascript 灵活的网站广告解决方案
    我自己Diy的asp.net mvc框架,支持多级目录!
    在asp.net mvc中创建使用Linq to sql的分页控件
    用asp.net开发移动wap网站集成在线wap模拟器
    .net平台下的手机在线wap网站模拟器(附源代码)
    opensuse 11.1 安装flashplayer
    引用第三方类库的私有类与私有方法
    如何统计代码行执行的时间?
    linux mono 调用windows sqlServer 2005
  • 原文地址:https://www.cnblogs.com/Lis-/p/9496676.html
Copyright © 2020-2023  润新知