Codeforces Round #206 div1 C

CF的专业题解 :

The problem was to find greatest d, such that ai ≥ d,  aimodd ≤ 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 aimodd ≤ 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 那么就是满足条件的 

 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
",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 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3410612.html