Codeforces354 C. Vasya and Beautiful Arrays(前缀和,思维,cf2100)

题意:

在这里插入图片描述

解法:
需要有一个前置知识:
[x-k,x]中一定会有[1,k+1]的倍数,因此答案至少是k+1.

1. 当a[1]<=k+1, 答案为a[1].
2. 当a[1]>k+1, 先令ans=k+1. 随后枚举g=[k+2,]:
对于固定的g, 我们需要检查是否所有[a[i]-k,a[i]]都包含t*g, 其中t>=1, t*g表示g的倍数.
即a[i]-k<=t*g且t*g<=a[i], 发现不太好计算,
我们可以通过移项将式子变成a[i]>=t*g且a[i]<=t*g+k.
那么问题就变为判断是否所有a[i]都在[t*g, t*g+k]范围内.
我们枚举t, 遍历t*g, 统计[t*g, t*g+k]范围内有多少个a[i].
最后如果统计数量为n,则表明g满足条件,可以用来更新ans.

那么当t不同时, 不同的[t*g,t*g+k]会不会有交集呢? 如果有交集的话就会出现重复统计.
答案是不会。因为我们枚举g是从k+2开始的, 因此g一定>k, 即一定有t*g+k<(t+1)*g.
Code:
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define int long long
#define PI pair<int, int>
const int maxm=2e6+5;
const int mod=998244353;
int n,k;
int a[maxm];
int sum[maxm];
void solve(){
  cin>>n>>k;
  for(int i=1;i<=n;i++){
    cin>>a[i];
    sum[a[i]]++;
  }
  for(int i=1;i<maxm;i++){
    sum[i]+=sum[i-1];
  }
  sort(a+1,a+1+n);
  if(a[1]<=k+1){
    cout<<a[1]<<endl;
    return ; 
  }
  int ans=k+1;
  for(int i=ans+1;i<maxm;i++){
    int cnt=0;
    for(int j=i;j<maxm;j+=i){
      int l=j;
      int r=min(maxm-1,j+k);
      cnt+=sum[r]-sum[l-1];
    }
    if(cnt==n){
      ans=i;
    }
  }
  cout<<ans<<endl;
}
signed main() {
// #define MULTI_CASE
  ios::sync_with_stdio(0);
  cin.tie(0);
#ifndef ONLINE_JUDGE
  freopen("../in.txt", "r", stdin);
  freopen("../out.txt", "w", stdout);
#endif
#ifdef MULTI_CASE
  int T;
  cin >> T;
  while (T--)
#endif
    solve();
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值