「CF1628A」Meximum Array

题目简介

\(\mbox{MEX}\) 定义为最小的未在某个集合中出现的非负整数

操作步骤如下:

\(\ \ 1.\)\(a\) 数组中取出前 \(k\) 个数;
\(\ \ 2.\) 将这 \(k\) 个数的 \(\mbox{MEX}\) 放入 \(b\) 数组末尾;
\(\ \ 3.\)\(a\) 数组中删除这 \(k\) 个数;
\(\ \ 4.\) 如果 \(a\) 不为空,重复执行 \(1\)~\(4\)

\(b\) 数组的最大字典序。

分析

想要字典序尽可能大,需要满足如下条件:

\(\ \ 1.\) 排在前面的数字尽可能大;
\(\ \ 2.\) 数组长度尽可能大。

由此,制定贪心策略:\(a\)\(\mbox{MEX}\) 值为 \(x\) 时,尽可能选择最短的 \(\mbox{MEX front} = x\) 前驱。

这样能够满足\(a\) 的当前 \(\mbox{MEX}\) 已定的情况下,\(a\) 后面的 \(\mbox{MEX}\) 尽可能大,并且 \(b\) 尽可能长。

具体如何实现?

设定一个 \(f\) 数组和一个 \(d\) 数组

\(f_i\):数字 \(i\)\(a\) 的后继中出现了 \(f_i\) 次。
\(d_i\):数字 \(i\)\(a\) 的前驱中出现了 \(d_i\) 次。

定义 \(mex\) 为当前序列的 \(\mbox{MEX}\)\(mex\_front\) 为序列前驱的 \(\mbox{MEX}\)\(mex\_ nxt\)为序列后继的 \(\mbox{MEX}\)

第一遍求出整个 \(a\) 数组的 \(mex\) ,然后进行第二遍扫描:

\(\ \ 1.\)\(d_{a_i}+1\),对 \(f_{a_i}-1\)
\(\ \ 2.\) 求出当前 \(mex\_front\)
\(\ \ 3.\) 当发现 \(f_{a_i}=0\) ,则证明 \(a_i\) 不在 \(a\) 的后继中,更新 \(mex\_ nxt=\mbox{min}\ a_i\)
\(\ \ 4.\) 当发现 \(mex\_front = mex\),则将 \(mex\_front\) 计入答案中,让当前 \(mex=mex\_nxt\),让 \(mex\_front=0\),清空 \(d\) 数组,继续扫描。

\(AC\ Code\)

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int read(){
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x;
}
const int Maxn=2e5+5;
int a[Maxn];
int f[Maxn];
int d[Maxn];
int ans[Maxn];
int main(){
	int t=read();
	while(t--){
		memset(f,0,sizeof f);
		memset(d,0,sizeof d);
		int n=read();
		int mex=0;
		for(int i=1;i<=n;i++){
			a[i]=read();
			f[a[i]]++;
		}
		while(f[mex])mex++;
		int mex_front=0,mex_nxt=mex;
		int tot=0;
		for(int i=1;i<=n;i++){
			int &x=a[i];
			d[x]++;
			while(d[mex_front])mex_front++;
			f[x]--;
			if(!f[x])mex_nxt=min(mex_nxt,x);
			if(mex_front==mex){
				ans[++tot]=mex_front;
				mex=mex_nxt;
				for(int j=mex_front-1;j>=0;j--)
					d[j]=0;
				mex_front=0;
			}
		}
		printf("%d\n",tot);
		for(int i=1;i<=tot;i++)printf("%d ",ans[i]);
		putchar('\n');
	}	
	return 0;
}

$$-----EOF-----$$

posted @ 2022-02-19 10:37  AlienCollapsar  阅读(92)  评论(0编辑  收藏  举报
// 生成目录索引列表 // ref: http://www.cnblogs.com/wangqiguo/p/4355032.html // modified by: zzq