@ysner
2018-08-20T07:23:36.000000Z
字数 1485
阅读 2681
set
有长度为的数列。有次操作。
第次操作中,必须把中所有数字改为。
现在给出疑似最终数列,其中几个数被改成了。回答是否存在初始数列。
很显然的是,如果两个相同数之间存在比它们小的数,这个序列一定不合法。
同样,如果这个序列不存在值为的数,这个序列也不合法。
思考怎么填数。
首先,如果没有数列中没有数字,优先填。
其次,设数分别在该位左右两边存在,则该位应取。
再次,如果不存在,该位填。(因为绝对合法,且不可能干扰到其它位的填数)
然后想怎么维护这个。
考虑弄个维护,所有的第一个出现时,;所有的最后一个出现时,。
可删除大根堆也可以,只是写着麻烦。
还有,取中最后一个数可以用*--Q.end(),end不会真的自减。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<set>#define re register#define il inline#define ll long long#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))#define fp(i,a,b) for(re int i=a;i<=b;i++)#define fq(i,a,b) for(re int i=a;i>=b;i--)using namespace std;const int mod=45989,N=5e5+100;int n,m,top,a[N],L[N],R[N],mx,mn;set<int>Q;set<int>::iterator it;il int gi(){re int x=0,t=1;re char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();if(ch=='-') t=-1,ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x*t;}int main(){n=gi();m=gi();fp(i,1,n) a[i]=gi(),mx=max(mx,a[i]),mn=min(mn,a[i]);fq(i,n,1) if(!R[a[i]]) R[a[i]]=i;fp(i,1,n) if(!L[a[i]]) L[a[i]]=i;fp(i,1,n){if(a[i]==0){if(mx<m) a[i]=m,mx=m;else if(Q.size()) a[i]=*--Q.end();else a[i]=1;}else{if(L[a[i]]==i&&L[a[i]]<R[a[i]]) Q.insert(a[i]);if(R[a[i]]==i&&L[a[i]]<R[a[i]]) Q.erase(a[i]);if(Q.size()) if(a[i]<(*--Q.end())) {puts("NO");return 0;}}}if(mx<m) {puts("NO");return 0;}puts("YES");fp(i,1,n) printf("%d ",a[i]);puts("");return 0;}
