Codeforces Round #521 (Div. 3) E. Thematic Contests (离散化,二分)

-
题意:有\(n\)个话题,每次都必须选取不同的话题,且话题数必须是上次的两倍,第一次的话题数可以任意,问最多能选取多少话题数.
-
题解:我们首先用桶来记录不同话题的数量,因为只要求话题的数量,与话题是多少无关,所以我们可以开个新数组然后离散化一下,比如\(mp[5]=6\)可以离散化成\(disc[1]=6\),\(mp[7]=2\)可以离散化成\(disc[2]=2\),这样可以方便我们进行二分查找,然后我们对\(disc\)数组sort一下,从\([1,n]\)开始进行二分,每次去找\(pos\)之后是否第一个大于等于\(now\)的位置,如果没有就break,每次二分都维护一下答案的最大值即可.
-
代码:
int n; int x; map<int,int> mp; int disc[N]; int cnt; int res; int main() { //ios::sync_with_stdio(false);cin.tie(0); scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",&x); mp[x]++; } for(auto w:mp){ disc[++cnt]=w.se; } sort(disc+1,disc+1+cnt); for(int i=1;i<=n;++i){ int sum=0; int pos=1; int now=i; while(true){ int tmp=lower_bound(disc+pos,disc+1+cnt,now)-disc; if(disc[tmp]==0) break; sum+=now; now*=2; pos=tmp+1; } res=max(res,sum); } printf("%d\n",res); return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号