题意:
解法:
需要有一个前置知识:
[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() {
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;
}