目录
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 1≤t≤100) — 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 1≤n≤105, 0 ≤ k ≤ 1 0 9 0\le k\le 10^9 0≤k≤109) — 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 0≤ai≤109) — 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