1. 程式人生 > >1077E Thematic Contests 【二分答案】

1077E Thematic Contests 【二分答案】

問題 lose ont test spa 就是 const tar lld

題目:戳這裏

題意: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\n", 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\n", ans); 39 return 0; 40 }
View Code

1077E Thematic Contests 【二分答案】