Codeforces Round #206 div1 C
CF的专业题解 :
The problem was to find greatest d, such that ai ≥ d, ai mod d ≤ k holds for each i.
Let m = min(ai), then d ≤ m. Let consider two cases:
. In this case we will brute force answer from k + 1 to m. We can check, if number d is a correct answer in the following way:
We have to check that ai mod d ≤ k for some fixed d, which is equals to , where
. Since all these intervals [x·d..x·d + k] doesn't intersects each with other, we can just check that
, where cnt[l..r] — count of numbers ai in the interval [l..r].
我用汉语大体概括一下
对于 k值是大于等于数组里面的最小值a1的时候 那么肯定答案就是a1
else 就暴力枚举可能的答案d 对于可以减去[0-k] 把d整除的区间有 [d,..d+k] [2d..2d+k] [3d..3d+k]等等。。然后可以标记数组里出现的数 数下在这些区间出现的数有多少个 如果等于N 那么就是满足条件的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<queue> 8 #include<cmath> 9 using namespace std; 10 #define N 300010 11 #define M 1000000 12 int a[N],vis[2*M+10]; 13 int main() 14 { 15 int n,i,j,k,ans; 16 cin>>n>>k; 17 for(i = 1; i <= n ; i++) 18 { 19 cin>>a[i]; 20 vis[a[i]]++; 21 } 22 sort(a+1,a+n+1); 23 for(i = 1 ;i <= M*2 ;i++) 24 vis[i] += vis[i-1]; 25 if(k>=a[1]) 26 { 27 printf("%d\n",a[1]); 28 return 0; 29 } 30 for(i = k ; i <= a[n] ; i++) 31 { 32 int sum=0; 33 for(j = i ; j <= a[n] ; j+=i) 34 { 35 sum+=vis[j+k]-vis[j-1]; 36 } 37 if(sum==n) 38 ans = i; 39 } 40 cout<<ans<<endl; 41 return 0; 42 }