基本思路是每次确定上界..二分找下界的最小合法值....
那么关键就在于如何快速得出两个位置之间需要做的操作次数...如样例中的数据
a=6 3 4 0 2
先排序为:
a=0 2 3 4 6
预处理..算出要使小于a[i]的数要做几次操作才能全等于a[i]...那么对应的值为
s=0 2 4 7 15
如果要问3~6要全等于a[6]所需的操作次数..及3 4 6全等于6...先算出0 2 6的次数sum..然后用s[6]-sum..则是所需...而0 2 6的计算为 2*(a[6]-a[2])+s[2]....所以可以算出3 4 6要全为6...操作次数为s[6]-sum=15-10=5
Program:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define oo 2000000000
#define pi acos(-1)
using namespace std;
ll n,k,m,a[100005],s[100005];
int main()
{
scanf("%I64d%I64d",&n,&k);
ll i,j,sum,ans1,ans2;
for (i=1;i<=n;i++) scanf("%I64d",&a[i]);
sort(a+1,a+1+n);
s[0]=0;
for (i=2;i<=n;i++) s[i]=s[i-1]+(a[i]-a[i-1])*(i-1);
ans1=0;
for (i=1;i<=n;i++)
{
int l,r,mid;
l=0; r=i+1;
while (r-l>1)
{
mid=(l+r)/2;
sum=s[i]-(s[mid-1]+(mid-1)*(a[i]-a[mid-1]));
if (sum>k) l=mid;
else r=mid;
}
if (i-r+1>ans1)
{
ans1=i-r+1;
ans2=a[i];
}
}
printf("%I64d %I64d\n",ans1,ans2);
return 0;
}