codeforces cf 521(div3) E題
阿新 • • 發佈:2018-11-19
本題讓我重視到對lower_bound這個函式不是特別會用。
lower_bound(int * ,int *,int )
第一個引數是陣列首地址,由於c++語言的特殊性,傳入第一個引數可以是陣列首地址+i,表示從陣列第i個元素查詢(對於下標從1開始的陣列)
第二個引數是陣列末位+1,這裡可以把陣列最後一位想象成INF,從頭開始,如果發現哪一位大於等於要查詢的數字就返回哪一位的地址。
第三個引數是要查詢的數字。
然後這道題把所有數字離散化存入一個桶裡從小到大排序
然後從第一位到最後一位暴力列舉
1每次都要列舉每一個小於等於這一位上的數字,
2對於列舉的每個數字,每次用lower_bound查詢這一位數字後面的所有數字裡面第一個大於等於這個數字的數。
3然後把數字乘二,位置移到查詢到的位置,
直到位置超出陣列總數後更新答案。
#include<bits/stdc++.h> using namespace std; int a[200010]; int aa[200010]; int b[200010]; int cnt[200010]; int tot; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); //將a[i]離散化 sort(a+1,a+n+1); aa[++tot]=a[1]; for(int i=2;i<=n;i++) { if(a[i]!=a[i-1]) { aa[++tot]=a[i]; //去重,tot是陣列中有幾個不同的數字 } } for(int i=1;i<=n;i++) { b[i]=lower_bound(aa+1,aa+tot+1,a[i])-aa;//lower_bound只對有序陣列有效 } //b[i]裡面存了離散化陣列 //統計b[i]中有多少每個數字出現的個數 for(int i=1;i<=n;i++) { cnt[b[i]]++;//cnt有tot個數字 } sort(cnt+1,cnt+tot+1); int res=0; for(int i=1;i<=tot;i++) { int pos=i; for(int num=1;num<=cnt[pos];num++) { int now=0; int tmp=pos; int num1=num; while(tmp<=tot) { now+=num1; tmp=lower_bound(cnt+tmp+1,cnt+tot+1,num1*2)-cnt; num1*=2; } res=max(res,now); } } printf("%d\n",res); }