zoukankan      html  css  js  c++  java
  • 1077E Thematic Contests 【二分答案】

    题目:戳这里

    题意:n个数代表n个problem,每个数的值代表这个问题的topic,让我们挑出一些problems,满足挑出problems的topic是首项为a1公比为2的等比数列(每种topic只能选一次。问最多能挑出多少个problems。

    解题思路:可以看出这道题只和每个topic的数量有关,我们记录每个topic的数量并排序。n的范围是2e5,也就是最后选出来的topic最多21个。所以只需要枚举等比数列的a1,二分查找是否有满足条件的a1*2^x即可。注意每种topic只能选一次,所以每次找出一个topic,二分的范围就要缩小一下,具体看代码。

     1 #include <bits/stdc++.h>
     2 typedef long long ll;
     3 const int maxn = 1e6+10;
     4 const ll inf = 1e18;
     5 using namespace std;
     6 ll a[maxn];
     7 map<ll, int>mp;
     8 int cnt[maxn];
     9 int main(){
    10     int n;
    11     scanf("%d", &n);
    12     for(int i = 1; i <= n; ++i) {
    13         scanf("%lld", a+i);
    14         ++mp[a[i]];
    15     }
    16     int newn = 0, maxx = 0;
    17     for(auto i: mp) {
    18         cnt[++newn] = i.second;
    19         maxx = max(maxx, i.second);
    20     }
    21     sort(cnt + 1, cnt + 1 + newn);
    22     int ans = 0;
    23     for(int i = 1; i <= maxx; ++i) {//21
    24         int pos = 1, mul = 1;
    25         int sum = 0;
    26         while(pos <= newn) {
    27             pos = lower_bound(cnt + pos, cnt + 1 + newn,mul * i) - cnt;
    28      //       printf("%d pos, %d mul %d sum
    ", pos, mul,sum);
    29             if(pos > newn) break;
    30             else {
    31                 sum += mul * i;
    32                 ++pos;
    33             }
    34             mul *= 2;
    35         }
    36         ans = max(ans, sum);
    37     }
    38     printf("%d
    ", ans);
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    Java String字符串深入详解
    每日linux命令学习-sed
    每日linux命令学习-历史指令查询(history、fc、alias)
    每日linux命令学习-rpm命令
    每日linux命令学习-head命令和tail命令
    每日linux命令学习-lsattr和chattr
    每日linux命令学习-xargs命令
    每日linux命令学习-read命令
    测试mysql性能工具
    mysql 免安装版文件含义及作用
  • 原文地址:https://www.cnblogs.com/zmin/p/9977848.html
Copyright © 2011-2022 走看看