poj 2689 大范围素数
题意:求大区间A B内离的最近和最远的两个素数,A B<=2,147,483,647。
分析:先用大素数的线性筛法,预处理出1~sqrt(2,147,483,647)的所有素数,然后用 b[0] ~ b[B-A],来表示A+(0) ~ A+(B-A)的数是否是素数。。
即若素数p*k = A+x --> A+x不是素数 --> b[x]=1 。
#define Max 2147483647 #define maxn 50000 int prime[maxn],p; bool vis[maxn] ; void getPrime(int n){//大范围内素数的线性筛法 FOE(i,2,n){ if( !vis[i]) prime[p++] = i; for(int j = 0;j < p && prime[j] * i <= n; j++){ vis[prime[j] * i] = true; if(i % prime[j] == 0)break; } } } int pri[500000],q; bool v[1000000]; void getPri(int a,int b){//求区间a b的素数 //prime[0~p]先存放2到sqrt(b_max)的素数 memset(v,0,(b-a+3)*sizeof(bool)); q=0; for(int i = 0; prime[i]*prime[i] <= b && i < p;i++){ long long k = a/prime[i]; if (k*prime[i] < a) k++; if (k <= 1) k++; while(k*prime[i] <= b){ v[k*prime[i] - a] = 1; k++; } } FOE(i,0,b-a) if(v[i] == 0) pri[q++] = a+i; } int L,U; void solve(){ int x1,x2,y1,y2; x1=x2=-1; y2=Max; y1=0; FOR(i,1,q){ if(x2-x1<pri[i]-pri[i-1])x1=pri[i-1],x2=pri[i]; if(y2-y1>pri[i]-pri[i-1])y1=pri[i-1],y2=pri[i]; } if(L==1){ if(U==2) cout<<"There are no adjacent primes."<<endl; else if(U<5) cout<<2<<","<<3<<" are closest, "<<2<<","<<3<<" are most distant."<<endl; else cout<<2<<","<<3<<" are closest, "<<x1<<","<<x2<<" are most distant."<<endl; }else if(x1==-1)cout<<"There are no adjacent primes."<<endl; else cout<<y1<<","<<y2<<" are closest, "<<x1<<","<<x2<<" are most distant."<<endl; } int main(){ int t=sqrt((double)Max); getPrime(t); while(cin>>L>>U){ getPri(L,U); solve(); } return 0; }