http://codeforces.com/contest/355/problem/Eios
每一個數均可以變成段 [a-k,a], 某一個因子是否被全部的段包含,就是把這個因子以及它的全部倍數當作點,數組
看是否是全部的段包含點spa
假如說全部的 a-k都大於0 那麼最小的 k+1這個因子必定是全部段都包含的code
若是有的段被0截斷了(a-k不大於0)那麼全部段都包含的最大因子就是最小段(0,a)的 ablog
假如全部段都沒有被截斷,最小可能解是k+1, 而後依次向上枚舉 對於全部大於k的因子,每個段要麼包含一個點,要麼不包含點ci
把全部的段在數組上標記,這樣很快就能夠斷定一個因子是否是被全部的段包含了get
代碼:string
#include<iostream> #include<stack> #include<cstdio> #include<queue> #include<cstring> #include<algorithm> #include<vector> #include<set> #include<map> #include<string> #include<cmath> using namespace std; typedef long long ll; typedef pair<int,int> pp; const double eps=1e-6; const int INF=0x3f3f3f3f; const int N=1000005; int d[N]; int main() { //freopen("data.in","r",stdin); int n,k; while(cin>>n>>k) { memset(d,0,sizeof(d)); int m=INF; for(int i=0;i<n;++i) { int l,r; cin>>r; m=min(m,r); if(m<=k+1) continue; l=r-k; ++d[l];--d[r+1]; } if(m<=k+1) cout<<m<<endl; else { for(int i=1;i<=1000000;++i) d[i]+=d[i-1]; int ans=k+1; for(int i=k+2;i<=1000000;++i) { int num=0; for(int j=i;j<=1000000;j+=i) num+=d[j]; if(num==n) ans=i; } cout<<ans<<endl; } } return 0; }