考场思路:
倒着算就是
可以对一个数-1
可以合并两个数
可以证明只有0和0才能执行合并操作
然后模拟
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 1000001 void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } int a[N]; int main() { //freopen("multiset.in","r",stdin); // freopen("multiset.out","w",stdout); int n; read(n); int sum0=0,cnt=0,x; for(int i=1;i<=n;i++) { read(x); if(!x) sum0++; else a[++cnt]=x; } sort(a+1,a+cnt+1); long long ans=0,gather=0; for(int i=1;i<=cnt;i++) { if(!a[i]) break; a[i]-=gather; x=a[i]; gather+=x; ans+=x; while(x) { x--; if(sum0>1) sum0=sum0+1>>1; else break; } sum0++; while(i<cnt && a[i+1]-gather==0) { sum0++; a[++i]-=gather; } } while(sum0>1) ans++,sum0=sum0+1>>1; cout<<ans; }