[CF1077E] Thematic Contests

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;
}
原文地址:https://www.cnblogs.com/mollnn/p/12836025.html