Posted on Symbols count in article: 3.6kReading time ≈8 mins.
比较简单的前置知识。
筛质数
1. 埃氏筛法
比较简单,算法核心就是直接将所有该质数的所有倍数筛掉。
1 2 3 4 5 6 7
for (int i=2;i<=n;++i) { if (isprime[i]) prime[cnt++]=i; elsebreak; for (int j=2*i;j<=n;j+=i) isprime[j]=false; }
时间复杂度为 $O(n*(1/2+1/3+…))=O(n \log \log n)$。
2. 线性筛法
先看代码。
1 2 3 4 5 6 7 8 9
for (int i=2;i<=n;++i) { if (isprime[i]) prime[cnt++]=i; for (int j=0;j<cnt&&i*prime[j]<=n;++j) { isprime[i*prime[j]]=false; if (i%prime[j]==0) break; } }
constint N=1e5+10; int prime[N],cnt; bool isprime[N];
voidinit() { for (int i=2;i<N;++i) isprime[i]=true; for (int i=2;i<N;++i) { if (isprime[i]) prime[cnt++]=i; for (int j=0;j<cnt&&i*prime[j]<N;++j) { isprime[i*prime[j]]=false; if (!(i%prime[j])) break; } } return ; }
intmain() { init(); int n;cin>>n; if (n>=3) puts("2"); elseputs("1"); for (int i=1;i<=n;++i) if (isprime[i+1]) printf("1 "); elseprintf("2 "); return0; }
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #define mp make_pair #define x first #define y second usingnamespace std;
voidinit() { memset(isprime,true,sizeof isprime); for (int i=2;i<N;++i) { if (isprime[i]) prime[cnt++]=i; for (int j=0;j<cnt&&prime[j]*i<N;++j) { isprime[i*prime[j]]=false; if (!(i%prime[j])) break; } } }
intmain() { init(); while (cin>>l>>r) { memset(vis,0,sizeof vis); for (int i=0;i<cnt;++i) { ll p=prime[i],low=(l+p-1)/p,high=r/p; for (int j=max((ll)2,low);j<=high;++j) vis[p*j-l]=true; } ll maxn=0,minx=INF; PLL maxp,minp; for (int i=0,last=-1;i<=r-l;++i) if (!vis[i]&&i+l>=2) { if (~last) { if (maxn<i-last) maxn=i-last,maxp=mp(last+l,i+l); if (minx>i-last) minx=i-last,minp=mp(last+l,i+l); } last=i; } if (maxn==0) puts("There are no adjacent primes."); elseprintf("%lld,%lld are closest, %lld,%lld are most distant.\n" ,minp.x,minp.y,maxp.x,maxp.y); } }