#866 div1A

A. Constructive Problem

题意:给定一个长度为n的非负数组a,我们可以进行一次操作,操作是将l~r这个区间内的所有数变为k(k >= 0),得到b,能不能使mex(a)+ 1 = mex(b)

思路:我是先排了个序,去了一下重,然后得到的这个数组其实只有两种情况
7fadb345668574e200b410c44f14b05.jpg
cdc76ad46ad0e20e462b088d676162b.jpg
一种每两个数之间的增量为1
一种是每两个数之间的增量大于1
对于第一种情况
我们考虑原数组大小如果和去重后数组大小相同,这种情况是不能增大的
否则说明有重复元素,我们只需要将重复元素变为n+1即可也就是说一定有解
对于第二种情况
我们考虑第一个增量不为一的地方
假如这个地方的增量为2这样我们就需要将这包含这个数的最小区间内的所有数变成mex(a)+1
然后扫一遍check以下就做完了
假如第一个增量不为一的地方的增量>=3则一定有解

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int a[N], n;
vector<int>b;
void run()
{
	b.clear();
	cin >> n;
	for(int i = 1; i <= n; ++ i)	scanf("%d", &a[i]), b.push_back(a[i]);
	sort(b.begin(), b.end());
	if(n == 1 && a[1] == 0)
	{
		puts("NO");
		return;	
	}	
	b.erase(unique(b.begin(), b.end()), b.end());
	if(b[0] != 0)	
	{
		puts("YES");
		return;
	}
	if(b.size() - 1 == b[b.size() - 1])
	{
		if(n == b.size())
		{
			puts("NO");
			return;
		}
		else
		{
			puts("YES");
			return;
		}
	}
	int t = 0;
	for(int i = 0; i < b.size(); ++ i)
	{
		if(b[i] != i)	break;
		t = i;
	}
	if(b[t + 1] - b[t] >= 3)	puts("YES");
	else
	{
		int l = 0, r = 0;
		for(int i = 1; i <= n; ++ i)
		{
			if(a[i] == b[t + 1])
			{
				l = i;
				break;
			}
		}
		for(int i = n; i >= 1; -- i)
		{
			if(a[i] == b[t + 1])
			{
				r = i;
				break;
			}
		}
		map<int, int>mp;
		for(int i = 1; i <= n; ++ i)
		{
			if(i >= l && i <= r)	continue;
			mp[a[i]] = 1;
		}
		for(int i = 0; i <= b[t]; ++ i)
		{
			if(mp.find(i) == mp.end())
			{
				puts("NO");
				return;	
			}	
		} 
		puts("YES");
	}
}

int main()
{
//	freopen("1.in", "r", stdin);
	int t;cin >> t;
	while(t --)	run();	
	return 0;  
}
posted @   cxy8  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
点击右上角即可分享
微信分享提示