codeforces cf 521(div3) E题

本题让我重视到对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
",res);
}

  

原文地址:https://www.cnblogs.com/lishengkangshidatiancai/p/9978073.html