E. Thematic Contests 二分,离散化

题目意思是给你n个问题即数字,n的大小代表问题所在的话题,题目要求举办多场比赛,每场比赛的只能一种问题,且后一场比赛的问题必须是前一场的两倍,求举办比赛可能最多的问题总数

传送门

解题思路:将出现每种数字对应的话题从一开始标记,用a记录对饮数字出现的次数,排序后,枚举第一场可能的问题次数,之后二分查找后面是否存在问题的二倍数量存在就加上,直到不足二倍。

#include<bits/stdc++.h>
using namespace std;
map<int, int> mp;
const int maxn=2e5+10;
int a[maxn];
int main()
{
    int n;
    scanf("%d", &n);
    int cnt=0;
    for(int i=1; i<=n; i++)
    {
        int t;
        scanf("%d", &t);
        if(mp[t]==0)
            mp[t]=++cnt;
        a[mp[t]]++;
    }
    sort(a+1, a+1+cnt);
    int maxx=-1;
//    for(int i=1; i<=cnt; i++)
//        printf("%d ", a[i]);
//    printf("\n");
    for(int i=1; i<=a[cnt]; i++)
    {
        int ans=0;
        int la=1;
        for(int j=i; j<=a[cnt];j=j*2)
        {
            int pos=lower_bound(a+la,a+1+cnt,j)-a;
            if(pos==cnt+1)
                break;
            else
            {
                ans+=j;
            }
            la=pos+1;
        }
        maxx=max(maxx,ans);
    }
    printf("%d", maxx);
}

 

posted @ 2018-11-18 20:03  paranoid。  阅读(170)  评论(0编辑  收藏  举报