Description
有 $ n $ 个问题,问题的主题分别是 $ a_1,a_2,cdots,a_n $,需要组织一些专题比赛,同时要满足以下条件:一场专题比赛中的所有题目的主题相同;组织的所有专题比赛中主题互异;从第二场比赛开始,比赛中的题目数必须是前一场比赛题目数量的 $ 2 $ 倍,第一场比赛的题目数量可以是任意的。求所有比赛使用的题目数量之和的最大值。
Solution
把每个类型的问题压在一起,枚举每一个开始问题数目,检验答案时,维护一个当前位置 (pos),每次在 (pos) 后的段中二分,找到第一个可以容纳的题目类型,复杂度 (O(n log^2 n))
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int n,ind,a[N],ans=0;
map<int,int> mp;
signed main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) {
int x;
cin>>x;
mp[x]++;
}
for(auto &i:mp) {
a[++ind]=i.second;
i.second=ind;
}
sort(a+1,a+ind+1);
for(int i=1;i<=n;i++) {
int sum=0,x=i,pos=1;
while(true) {
int p=lower_bound(a+pos,a+ind+1,x)-a;
if(a[p]==0) break;
sum+=x;
x*=2;
pos=p+1;
}
ans=max(ans,sum);
}
cout<<ans;
}