Meximum Array-Codeforces Round #767 (Div. 1)

题目描述

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 aa of nn non-negative integers, Mihai wants to create a new array bb that is formed in the following way:

While aa is not empty:

  • Choose an integer kk ( 1 \leq k \leq |a|1≤k≤∣a∣ ).
  • Append the MEX of the first kk numbers of the array aa to the end of array bb and erase them from the array aa , shifting the positions of the remaining numbers in aa .

But, since Mihai loves big arrays as much as the MEX concept, he wants the new array bb to be the lexicographically maximum. So, Mihai asks you to tell him what the maximum array bb that can be created by constructing the array optimally is.

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

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}1,2,3 }) = 0=0 and MEX({ {0, 1, 2, 4, 5}0,1,2,4,5 }) = 3=3 .

输入格式

The first line of the input contains a single integer tt ( 1 \le t \le 1001≤t≤100 ) — the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer nn ( 1 \leq n \leq 2 \cdot 10^51≤n≤2⋅105 ) — the number of elements in the array aa .

The second line of each test case contains nn non-negative integers a_1, \ldots, a_na1​,…,an​ ( 0 \leq a_i \leq n0≤ai​≤n ), where a_iai​ is the ii -th integer from the array aa .

It is guaranteed that the sum of nn over all test cases does not exceed 2 \cdot 10^52⋅105 .

输出格式

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

要求得到字典序最大,根据贪心原则,靠前的数字越大越好,所以先不考虑长度,遍历数组,找到一个重来没有出现过的最大数,统计cnt,如果当前长度确定的mex在今后长度也不会出现,那么就停止本次寻找,转而寻找下一段,使得字典序最大。

对于每次遍历到的a[i],标记它,mex设置初始值0,while(book[mex])可以找到当前没有出现的最大值,如果这个mex今后也不会出现,那么显然这时候就是最优,如果mex今后还会出现,就继续找,因为mex出现的话,势必导致更大的mex出现,可以使字典序最大

# include <stdio.h>
#include<iostream>
# include<cstring>
using namespace std;
int a[200000+10];
int cnt[200000+10];
int b[200000+10];
bool book[200000+10];
int main()
{
   int t;
   cin>>t;

   while(t--)
   {
       int n;
       cin>>n;

       for(int i=1;i<=n;i++)
       {
           scanf("%d",&a[i]);
           cnt[a[i]]++;
       }
       int mex=0;
       int len=0;
       for(int i=1;i<=n;i++)
       {
           //截止到目前长度包含本次
           book[a[i]]=1;
           while(book[mex])
           {
               mex++;
           }
           //得到当前长度最大mex
           if(cnt[mex]==0)
           {
               //后面不会存在更大的mex
               b[len]=mex;
               len++;
               memset(book,0,sizeof(book));
               mex=0;//寻找下一段mex时必须归零


           }
           cnt[a[i]]--;
           //少一次

       }

        memset(book,0,sizeof(book));

       cout<<len<<'\n';
       for(int i=0;i<len;i++)
       {
           cout<<b[i]<<" ";
       }

       cout<<'\n';
   }

    return 0;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦三码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值