B. Max and Mex

Codeforces Round #706 (Div. 2) B

B. Max and Mex

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

You will perform the following operation k times:

Add the element ⌈a+b2⌉ (rounded up) into S, where a=mex(S) and b=max(S). If this number is already in the set, it is added again.
Here max of a multiset denotes the maximum integer in the multiset, and mex of a multiset denotes the smallest non-negative integer that is not present in the multiset. For example:

mex({1,4,0,2})=3;
mex({2,5,1})=0.
Your task is to calculate the number of distinct elements in S after k operations will be done.

Input
The input consists of multiple test cases. The first line contains a single integer t (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, k (1≤n≤105, 0≤k≤109) — the initial size of the multiset S and how many operations you need to perform.

The second line of each test case contains n distinct integers a1,a2,…,an (0≤ai≤109) — the numbers in the initial multiset.

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

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

Example
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
output
4
4
3
5
3

链接: B.

分析:
分为两种情况
1.当mex的值小于max时,更新出来的值 x > mex && x < max,所以mex的值与max的值一直都不变,此时若 x 的值与序列不同,则ans为 n + 1 ,否则为 n;
2.当mex的值大于max时,更新出来的值 x > max && x < mex , 四舍五入,max == x ;max的值一直改变, 每次更新出的 x的值也在改变,及操作k次,有k个不同的值,即 n + k;

代码

#include <iostream>
#include <algorithm>
 
using namespace std;
 
const int N = 1e5+10;
 
int  main()
{
	int t;
	cin >> t;
	while(t --)
	{
		long long n,k;
		int a[N];
		long long i;
		cin >> n >> k;
		for(i = 0;i < n;i ++)
		cin >> a[i];
		
		sort(a,a+n);//排序
    
	    int ans;		
		if(k == 0) ans = n; //注意判断 k == 0 的情况
	    else
		{
		long long mex,max;
		int flag1 = 0;
		for(i = 0;i < n;i ++)
		{
			if(a[i] != i)
			{
				mex = i;
				flag1 = 1;
				break;
			}
		} //找出mex
		
		if(flag1 == 0) mex = n;
        max = a[n-1];	//找出max
	    
	    if(mex < max)
	    {
	    	double add = (mex + max) * 1.0 / 2;
	    	long long x = (long long)(add + 0.5);//四舍五入
	    
	    	int flag2 = 0;
	    	for(i = 0;i < n;i ++)
	    	{
	    		if(a[i] == x)
	    	    {
	    	    	ans = n ;
	    	    	flag2 = 1;
	    	    	break;
	    	    }
	    	} //判断是否与已知序列元素相等
	    	if(flag2 == 0)
	    	ans = n+1;
	    	
	    }else 
	    	 ans = n + k;
	    }
	 
            cout << ans << endl;
	}
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值