0
点赞
收藏
分享

微信扫一扫

Codeforces Round #767 (Div. 2) C. Meximum Array 计算MEX

雅典娜的棒槌 2022-01-23 阅读 142
c++

MEX
即取mex集合中没有出现过的最小非负整数
如:mex{0,2,3}=1;
mex{1,2,3}=0;

题意:Mihai has just learned about the MEX concept and since he liked it so much, he decided to use it right away.

Given an array a of n non-negative integers, Mihai wants to create a new array b that is formed in the following way:

While a is not empty:

Choose an integer k (1≤k≤|a|).
Append the MEX of the first k numbers of the array a to the end of array b and erase them from the array a, shifting the positions of the remaining numbers in a.
But, since Mihai loves big arrays as much as the MEX concept, he wants the new array b to be the lexicographically maximum. So, Mihai asks you to tell him what the maximum array b that can be created by constructing the array optimally is.

An array x is lexicographically greater than an array y if in the first position where x and y differ xi>yi or if |x|>|y| and y is a prefix of x (where |x| denotes the size of the array x).

The MEX of a set of non-negative integers is the minimal non-negative integer such that it is not in the set. For example, MEX({1,2,3}) =0 and MEX({0,1,2,4,5}) =3.
Input
The first line of the input contains a single integer t (1≤t≤100) — the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer n (1≤n≤2⋅105) — the number of elements in the array a.

The second line of each test case contains n non-negative integers a1,…,an (0≤ai≤n), where ai is the i-th integer from the array a.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case print m — the length of the maximum array b Mihai can create, followed by m integers denoting the elements of the array b.

从头到尾遍历数组(这里采用l,r定点),直至找到那个最小未出现的数,更新l,r的位置,以此类推直到将整个数组遍历完。

#include<bits/stdc++.h>
using namespace std;
int t,n;
int a[220001];
queue<int>q[220001];
vector<int>ans;
int main()
{
	cin>>t;
	while(t--)
	{
		ans.clear();
		cin>>n;
		for(int i=1;i<=n;i++)//存储每个数分别出现的位置
		{
			cin>>a[i];
			q[a[i]].push(i);
		}
		int l=1,r=0;
		while(l<=n)
		{
			r=l;
			for(int i=0;i<=n+1;i++)
			{
				if(q[i].empty())//找出最小未出现的数
				{
					ans.push_back(i);//存结果
					break;
				}
				r=max(r,q[i].front());//找到mex的最右端。
			}
			for(int i=l;i<=r;i++)//模拟将前一段mex抹除的过程
			{
				q[a[i]].pop();
			}
			l=r+1;//开启下一段
		}
		cout<<ans.size()<<endl;
		for(int i=0;i<ans.size();i++)
		{
			cout<<ans[i]<<' ';
		}
		cout<<endl;
	}
} 
举报

相关推荐

0 条评论