B:纸牌游戏
因为所有人都想要尽可能少人,所以只有当且仅当每个人都能从别人拿刚好拿走1张牌的时候是人数最大的情况。对于此情况从小到大排个序a[i]>=i的时候n-i+1就是答案,比赛的时候写复杂了写了个树状数组,1到a[i]全部+1,只要查询单点大于i就行。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2555555; inline ll read(){ ll s=0,f=1;char c=getchar(); while(c<'0'||c>'9'){ if(c=='-')f=-1;c=getchar(); } while(c>='0'&&c<='9'){ s=(s<<1)+(s<<3)+(c^48);c=getchar(); } return f*s; } bool vis[555]; ll n,a[N]; inline int lowbit(int x){ return -x & x; } void add(int x,int s) { while(x<=n) { a[x]+=s; x+=lowbit(x); } } long long int sum(int x) { long long int s=0; while(x) { s+=a[x]; x-=lowbit(x); } return s; } int main(){ n=read(); for(int i=1;i<=n;i++){ add(1,1); add(min(read()+1,n+1),-1); } for(int i=n;i>=1;i--){ if(sum(i-1)>=i){ cout<<i<<endl; break; } } return 0; }