E. Thematic Contests
题目链接:https://codeforces.com/contest/1077/problem/E
题意:
给出n个数,然后你可以规定一个基数x,第一次选x个相同的数出来,第二次选2*x出来,第三次选4*x个出来....问最后最多选多少个数出来。
题解:
这个没想到暴力算就行了,但是这个暴力也还是有技巧的。
我们先把数离散化一波并且排个序,这样方便我们知道哪些数出现了多少次,然后就枚举基数k,每次二分查找看有没有当前这个数,有的话k*=2,然后继续从当前位开始往下查找。
最后维护一下答案就行了。
代码如下:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5+5; int a[N],b[N]; int n; multiset <ll> s; map <int,int> mp; int main(){ scanf("%d",&n); int cnt = 0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); if(!mp[a[i]]) mp[a[i]]=++cnt; b[mp[a[i]]]++; } sort(b+1,b+cnt+1); ll ans = 0; ll sum; int next,Begin; for(int i=1;i<=b[cnt];i++){ ll k = i; sum = 0; Begin = lower_bound(b+1,b+cnt+1,k)-b; while(1){ if(Begin==cnt+1) break ; sum+=k; k*=2; Begin++; next = lower_bound(b+Begin,b+cnt+1,k)-b; Begin = next ; } ans=max(ans,sum); } cout<<ans; return 0; }