题目链接:http://poj.org/problem?id=2689
Time Limit: 1000MS Memory Limit: 65536K
Description
Input
Output
Sample Input
2 17 14 17
Sample Output
2,3 are closest, 7,11 are most distant. There are no adjacent primes.
题意:
给出 $st$ 与 $ed$ ($1 \le st < ed \le 2147483647$ 且 $ed - st \le 1e6$),求 $[st,ed]$ 区间内,相邻的两个素数中,差最小的和差最大的(若存在差同样大的一对素数,则有先给出最小的一对素数);
题解:
显然,不可能直接去筛 $2147483647$ 以内的素数;
由于任何一个合数 $n$ 必定包含一个不超过 $\sqrt{n}$ 的质因子,
那么,我们不妨先用欧拉筛法筛出 $[0,46341]$ 区间内的素数($46341 \approx \sqrt{2147483647}$);
然后对于每个test case的 $[st,ed]$ 区间,用筛出来的质数再去标记 $[st,ed]$ 内的合数,剩下来的就是质数了。
AC代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #define pb(x) push_back(x) using namespace std; typedef long long ll; const int maxn=1e6+5; vector<ll> p; bool vis[maxn]; const int MAX=46350; bool noprm[MAX+3]; vector<int> prm; void Erato() { noprm[0]=noprm[1]=1; for(int i=2;i<=MAX;i++) { if(noprm[i]) continue; prm.pb(i); for(int j=i;j<=MAX/i;j++) noprm[i*j]=1; } } int main() { Erato(); ll L,R; while(cin>>L>>R) { for(ll i=L;i<=R;i++) vis[i-L]=0; for(int i=0;i<prm.size();i++) { ll st=max(2LL,L/prm[i]+(L%prm[i]>0)), ed=R/prm[i]; for(ll k=st;k<=ed;k++) vis[k*prm[i]-L]=1; } if(L==1) vis[0]=1; p.clear(); for(ll i=L;i<=R;i++) if(!vis[i-L]) p.pb(i); if(p.size()<=1) cout<<"There are no adjacent primes.\n"; else { int mn=1, mx=1; for(int i=1;i<p.size();i++) { if(p[i]-p[i-1]<p[mn]-p[mn-1]) mn=i; if(p[i]-p[i-1]>p[mx]-p[mx-1]) mx=i; } printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n",p[mn-1],p[mn],p[mx-1],p[mx]); } } }
POJ 2689 - Prime Distance - [埃筛]
原文:https://www.cnblogs.com/dilthey/p/7577275.html