感觉是很有意思的一道题呢~

开 始 我 想 的 是 一 种 数 字 最 多 出 现 连 续 的 一 段 开始我想的是一种数字最多出现连续的一段

但 是 如 果 后 面 的 区 间 覆 盖 在 前 面 区 间 的 中 间 呢 ? 但是如果后面的区间覆盖在前面区间的中间呢? ?

那 么 一 种 数 字 就 分 成 了 多 段 . . . . . . . 那么一种数字就分成了多段....... .......

但 在 这 样 的 考 虑 当 中 , 不 合 法 的 情 况 也 浮 出 水 面 . . . . . 但在这样的考虑当中,不合法的情况也浮出水面..... ,.....

Ⅰ . 数 字 x 出 现 的 最 左 端 是 l , 最 右 端 是 r , 那 么 [ l , r ] 不 能 比 x 小 \color{Red}Ⅰ.数字x出现的最左端是l,最右端是r,那么[l,r]不能比x小 .xl,r,[l,r]x

Ⅱ . 数 字 q 一 定 出 现 , 因 为 是 最 后 一 次 染 色 , 不 会 被 别 人 覆 盖 \color{Red}Ⅱ.数字q一定出现,因为是最后一次染色,不会被别人覆盖 .q,,

如 果 既 没 有 数 字 q , 也 没 有 数 字 0 能 填 充 q , 那 么 也 不 合 法 如果既没有数字q,也没有数字0能填充q,那么也不合法 q,0q,

如 果 上 面 都 满 足 条 件 , 那 么 把 所 有 的 0 填 充 为 附 近 的 数 即 可 如果上面都满足条件,那么把所有的0填充为附近的数即可 ,0

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,q,a[maxn],ans[maxn][21];
vector<int>vec[maxn];
void over(){
	cout<<"NO";exit(0);
}
int query(int l,int r){
	int k=log2(r-l+1);
	return min(ans[l][k],ans[r-(1<<k)+1][k]);
}
void Make_St()
{
	for(int j=1;j<=21;j++)
	for(int i=1;i+(1<<j)-1<=n;i++)
		ans[i][j]=min(ans[i][j-1],ans[i+(1<<(j-1))][j-1]);
}
int main()
{
	cin>>n>>q;
	memset(ans,20,sizeof(ans));
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		if(a[i]!=0)	ans[i][0]=a[i];
	}
	Make_St();
	for(int i=1;i<=n;i++)
	{
		if(a[i]==0)	continue;
		else if(a[i]==a[i-1])	continue;
		else	vec[a[i]].push_back(i);
	}
	for(int i=1;i<=q;i++)
	{
		int top=vec[i].size();
		if(top>=2)
		{
			int l=vec[i][0],r=vec[i][top-1];
			if(query(l,r)<i)	over();
		}
	}
	if(vec[q].size()==0)//最后一个数一定存在 
	{
		int flag=0;
		for(int i=1;i<=n;i++)
			if(a[i]==0)
			{
				flag=1,a[i]=q;
				break;
			}
		if(!flag)	over();
	}
	for(int i=1;i<=n;i++)	if(a[i]==0)	a[i]=a[i-1];
	for(int i=n;i>=1;i--)	if(a[i]==0)	a[i]=a[i+1];
	cout<<"YES"<<endl;
	for(int i=1;i<=n;i++)	cout<<a[i]<<" ";
}

树状数组版本

树 状 数 组 怎 么 做 ? ? 树状数组怎么做?? ??

设 x 数 出 现 在 l 位 置 和 r 位 置 设x数出现在l位置和r位置 xlr

那 么 要 求 l 到 r 间 没 有 比 x 小 的 数 , 也 就 是 l 位 置 前 小 于 x 的 数 那么要求l到r间没有比x小的数,也就是l位置前小于x的数 lrx,lx

等 于 r 位 置 之 前 小 于 x 的 数 等于r位置之前小于x的数 rx

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,q,a[maxn],vis[maxn];
void over(){
	cout<<"NO";exit(0);
}
class Binary_Search_Tree
{
	private:
		int sumn[maxn];
		int lowbit(int x){	return x&(-x);	}
	public:
		void add(int x){
			for(;x<=q;x+=lowbit(x))	sumn[x]++;
		}
		int ask(int x){
			int ans=0;
			for(;x;x-=lowbit(x))	ans+=sumn[x];
			return ans;
		}
}bit;
int main()
{
	cin>>n>>q;
	int ff=0;
	for(int i=1;i<=n;i++)	cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		if(a[i]==0)	continue;
		if(vis[a[i]])	if(bit.ask(a[i])!=vis[a[i]])	over();	
		bit.add(a[i]);
		vis[a[i]]=bit.ask(a[i]);
		if(a[i]==q)	ff=1;
	}
	if(ff==0)//最后一个数一定存在 
	{
		int flag=0;
		for(int i=1;i<=n;i++)
		if(a[i]==0)
		{
			flag=1,a[i]=q;
			break;
		}
		if(!flag)	over();
	}
	for(int i=1;i<=n;i++)	if(a[i]==0)	a[i]=a[i-1];
	for(int i=n;i>=1;i--)	if(a[i]==0)	a[i]=a[i+1];
	cout<<"YES"<<endl;
	for(int i=1;i<=n;i++)	cout<<a[i]<<" ";
}