【CodeForces - 305C】Ivan and Powers of Two(思维)

C. Ivan and Powers of Two

time limit per test

0.5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Ivan has got an array of n non-negative integers a1, a2, ..., an. Ivan knows that the array is sorted in the non-decreasing order.

Ivan wrote out integers 2^{a1}, 2^{a2}, ..., 2^{an} on a piece of paper. Now he wonders, what minimum number of integers of form 2^b (b ≥ 0) need to be added to the piece of paper so that the sum of all integers written on the paper equalled 2^v - 1 for some integer v (v ≥ 0).

Help Ivan, find the required quantity of numbers.

Input

The first line contains integer n (1 ≤ n ≤ 105). The second input line contains n space-separated integers a1, a2, ..., an (0 ≤ ai ≤ 2·109). It is guaranteed that a1 ≤ a2 ≤ ... ≤ an.

Output

Print a single integer — the answer to the problem.

Examples

input

Copy

4
0 1 1 1

output

Copy

0

input

Copy

1
3

output

Copy

3

Note

In the first sample you do not need to add anything, the sum of numbers already equals 2^3 - 1 = 7.

In the second sample you need to add numbers 2^0,2^1,2^2.

思路:

一开始没想到怎么做,但是看数据量这么大就一定是思维题,写了写发现要求得就是许多个2^k的加和,并且和还是2的指数,而由2的指数得到2的指数,那就是两个相同的相加使得指数加1。即2^{k}+2^{k}=2*2^k=2^{k+1},因此我们只要暴力遍历所有的数,找相邻两个数之间的差值就是我们要补的数的多少,如果一对数是1,3那么我们添加几个数后应该变为4(使得两个数变为1个)。小的数在不断添加数的过程中会增加,直到和大的数相等,这时我们不必在加新的数,只需要这两个数相加就好。由此我们能发现要补的数是t1、t1+1....t2-1(t1\leq t2)。因此这两个数之间需要补的数是t2-t1个。

这里我用来优先队列,但是直接用数组模拟应该也是可以的。greater从小到大的优先级队列。

ac代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<string.h>
#define ll long long
using namespace std;
priority_queue<ll,vector<ll>,greater<ll> > que;
ll a[110100];
int main() 
{
	int n;
	scanf("%d",&n);
	a[0]=0;
	que.push(0);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		que.push(a[i]);
	}
	ll ans=0;
	while(!que.empty())
	{
		ll t1=que.top();
		que.pop();
		ll t2=que.top();
		que.pop();
		if(t1==t2)
		{
			if(que.empty())
			{
				break;
			}
			else
			{
				que.push(t1+1);
			}
		}
		else
		{
			int dis=t2-t1;
			ans+=dis;
			if(que.empty())
			{
				break;
			}
			else
			{
				que.push(t2+1);
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}

 

 cf上大佬们写的代码就行简单,自己写的还是太麻烦了,ORZ。

个人的理解:
感觉就是,0~v时,我一开时什么都没有,然后从0~v需要0~v-1这几个数和0这个数。而0我一开始有1个
那么0~v-1一共有v个那么我一开始缺少k个。然后读入数后进行合并并放入set中,那么set中是我现在有的,即我不用再额外找这些数了。
但是set中的最大值就是v,而这个本来就不需要,因此不应该算在已有的里面,所以现在已有的是s.size()-1。
需要的-已经有的=要补的 

#include<bits/stdc++.h>
using namespace std;
set<int> s;
int a,n,k;
int main(){
	cin>>n;
	while (n--){
		cin>>a;
		while (s.count(a))
		s.erase(a),a++;
		s.insert(a),
		k=max(k,a);//能到的最大值,应该就是v    读入的数的最大值再加一 
	}
	cout<<k-s.size()+1;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值