codeforce1364C. Ehab and Prefix MEXs

このせかいもわるくない

给一个a数组,找一个b数组,要求在集合 { b 1 , b 2 , , b i } \{ b_1,b_2,\cdots,b_i \} 以外的整数中,最小的是 a i a_i


首先可以确定的一点是 a i a i 1 a_i\neq a_{i-1} 的时候, b i = a i 1 b_i=a_{i-1}
那么剩下的位置就有很大操作空间了,最简单的方法就是从 a m a x + 1 a_{max}+1 开始向剩余位置填数,这样造出来的序列一定满足要求,就是b有点大,不太符合输出要求,所以我们把没有在a中出现的数字依次填进去,反正这些位置不怎么重要,而且这些玩意填进去也不影响a。
至于怎么判断是否存在这么一个b,只需要判断 a [ i ] a[i] i i ,因为 a [ i ] a[i] 是b
中前i个元素之外最小的。例如 a [ 5 ] = 4 a[5]=4 ,那么b的前五个元素中一定包含 { 0 1 2 3 } \{0,1,2,3\} ,否则 a [ 5 ] 4 a[5]\leq 4 ,所以只需要判断前 i i 个位置里有没有足够的空填数就可以了
但是看过题解之后我明白这居然真的是个水题,我太菜了TAT

#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

template<class T> void _deb(const char *name,T val){
    cout<<name<<val<<endl;
}

const int maxn=1e5+5;

int a[maxn];
int b[maxn];
bool appear[(int)1e6+5];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin>>n;
    rep(i,1,n+1){
        cin>>a[i];
        appear[a[i]]=true;
        b[i]=-1;
    }

    bool flag=true;
    rep(i,2,n+1){
        if(a[i]!=a[i-1])
            b[i]=a[i-1];
        if(a[i]>i){
            flag=false;
            break;
        }
    }

    if(!flag){
        cout<<"-1"<<endl;
        re 0;
    }

    int teriri=0;
    rep(i,1,n+1){
        if(b[i]>=0)
            continue;
        while(appear[teriri])
            teriri++;
        b[i]=teriri;
        teriri++;
    }

    rep(i,1,n+1)
        cout<<b[i]<<" ";
        cout<<endl;

    re 0;
}

猜你喜欢

转载自blog.csdn.net/white_156/article/details/106951466