topic
train of thought
You can adopt the idea that the opposite is the opposite.
If we want x to be the answer , then we only need to reduce all the numbers to the nearest multiple of x (and the multiple must also be <= x )
In this case, the complexity of O(n^2)
But the data is huge, so it can only be done in O(n) or O(log(n))
Then we can set pre[i] to be the number of numbers whose subscript is less than i ,
sum[i] is the sum of numbers with subscripts less than i
In fact , for x , all numbers in a certain interval [k*x, (k+1)*x-1 ] are changed to k*x
Then we can use the prefix sum to calculate the number of the interval and -k*x* the number of numbers in the interval to calculate the result,
the code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int ans,n,m,pre[10000001],cnt[10000001],t,sum[10000001];
bool f(int x)
{
int s = 0;
for(int k = 0; k * x <= 1000001; k++)
s += (sum[x * (k + 1) - 1] - sum[k * x - 1] - (int)k * x * (pre[x * (k + 1) - 1] - pre[k * x - 1]));
if(s <= m) return 1;
return 0;
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(int i = 1; i <= n; i++)
{
scanf("%lld",&t);
cnt[t]++;
}
for(int i = 1; i <= 2000000; i++) sum[i] = sum[i - 1] + cnt[i] * i;
for(int i = 1; i <= 2000000; i++) pre[i] = pre[i - 1] + cnt[i];
for(int x = 1; x <= 1000000; x++)
if(f(x))
ans = x;
printf("%lld",ans);
return 0;
}
/*
5 2
5 6 7 6 5
*/