#B. Equipment configuration of gsy

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
*/

Guess you like

Origin blog.csdn.net/weq2011/article/details/128901703