Codeforces Round #706 (Div. 2)-B. Max and Mex-题解

Codeforces Round #706 (Div. 2)-B. Max and Mex

传送门
Time Limit: 1 second
Memory Limit: 256 megabytes

Problem Description

You are given a multiset S S S initially consisting of n n n distinct non-negative integers. A multiset is a set, that can contain some elements multiple times.

You will perform the following operation k k k times:

Here max ⁡ \operatorname{max} max of a multiset denotes the maximum integer in the multiset, and mex ⁡ \operatorname{mex} mex of a multiset denotes the smallest non-negative integer that is not present in the multiset. For example:

Your task is to calculate the number of distinct elements in S S S after k k k operations will be done.

Input

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

The first line of each test case contains two integers n n n, k k k ( 1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1n105, 0 ≤ k ≤ 1 0 9 0\le k\le 10^9 0k109) — the initial size of the multiset S S S and how many operations you need to perform.

The second line of each test case contains n n n distinct integers a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an ( 0 ≤ a i ≤ 1 0 9 0\le a_i\le 10^9 0ai109) — the numbers in the initial multiset.

It is guaranteed that the sum of n n n over all test cases does not exceed 1 0 5 10^5 105.

Output

For each test case, print the number of distinct elements in S S S after k k k operations will be done.

Sample Input

5
4 1
0 1 3 4
3 1
0 1 4
3 0
0 1 4
3 2
0 1 2
3 2
1 2 3

Sample Onput

4
4
3
5
3

Note

In the first test case, S = { 0 , 1 , 3 , 4 } S=\{0,1,3,4\} S={0,1,3,4}, a = mex ⁡ ( S ) = 2 a=\operatorname{mex}(S)=2 a=mex(S)=2, b = max ⁡ ( S ) = 4 b=\max(S)=4 b=max(S)=4, ⌈ a + b 2 ⌉ = 3 \lceil\frac{a+b}{2}\rceil=3 2a+b=3. So 3 3 3 is added into S S S, and S S S becomes { 0 , 1 , 3 , 3 , 4 } \{0,1,3,3,4\} {0,1,3,3,4}. The answer is 4 4 4.

In the second test case, S = { 0 , 1 , 4 } S=\{0,1,4\} S={0,1,4}, a = mex ⁡ ( S ) = 2 a=\operatorname{mex}(S)=2 a=mex(S)=2, b = max ⁡ ( S ) = 4 b=\max(S)=4 b=max(S)=4, ⌈ a + b 2 ⌉ = 3 \lceil\frac{a+b}{2}\rceil=3 2a+b=3. So 3 3 3 is added into S S S, and S S S becomes { 0 , 1 , 3 , 4 } \{0,1,3,4\} {0,1,3,4}. The answer is 4 4 4.


题目大意

MAX是一个集合中最大的数
MEX是一个集合中最小的非负整数
每次操作把 ⌈ M A X + M E X 2 ⌉ \lceil\frac{MAX+MEX}{2}\rceil 2MAX+MEX向上取整,得到的新数放入集合中。
问进行k次操作后,集合中有几种数。


题目分析

考虑两种情况,初始时 MEX ≥ \ge n 和 MEX ≤ \le n 。

MEX ≥ \ge n其实就是MEX=n

读者不妨计算几个试试,将会发现每进行一次操作,MEX就会+1,集合中不同元素的个数也就随之+1。k次操作后,集合中不同元素的个数就变成了n + k

MEX ≤ \le n

  • 如果k=0,不需要进行操作,答案就是最初的集合中不同元素的个数
  • 否则新生成的数Mnew一定是 ≥ \ge MEX并且 ≤ \le MAX的,每次操作都是这个数(因为新生成的数不会改变MEX和MAX)。

解题思路

读入n个a后,排序,遍历一遍得到MEX,并且用map去重。

  • 若是MEX ≥ \ge n,就输出n+k
  • 否则
    • 如果k=0,就直接输出map.size
    • 否则,计算一次新生成的数Mnew,并将Mnew插入到map中,输出map.size

map可以设置为map<int,bool>,map.size就是集合中不同元素的个数


AC代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
int a[100010];

int main()
{
    int N;
    cin >> N;
    while (N--) //N个测试样例
    {
        int n, k;
        scanf("%d%d", &n, &k);
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]); //读入
        }
        sort(a, a + n); //排序
        int Me = 0;
        map<int, bool> mp;
        for (int i = 0; i < n; i++)
        {
            mp[a[i]] = 1; //a[i]出现过,插入map
            if (a[i] == Me) //如果目前的Me出现过,就Me++
                Me++;
        }
        if (Me >= n) //第一种情况,直接输出
        {
            printf("%d\n", n + k);
            continue;
        }
        else //否则
        {
            map<int, bool>::iterator it = mp.end();
            it--;
            int Ma = it->first; //Ma就是map中的最后一个的first
            int Mnew = (Ma + Me) / 2 + ((Ma + Me) % 2 != 0); //操作后新生成的数
            if (k != 0) //k不等于0
                mp[Mnew] = 1;
            printf("%d\n", mp.size());
        }
    }
    return 0;
}

原创不易,转载请附上原文链接哦~
Tisfy:https://blog.csdn.net/Tisfy/article/details/114647849

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Tisfy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值