POJ2689 Prime Distance
坑死我了,除0导致re到si。还一直以为数组越界自闭了一早上。
题意:给定两个整数L、U。求闭区间中相邻两素数的差的最大值和最小值,输出这两个质数。LU的范围2e9。U-L范围1e6。
思路:
LU的范围2e9,直接线性筛子会 MLE&&TLE。但是U-L范围是1e6。
任何合数n必定包含一个不超过
n
\sqrt{n}
n的质因子。
所以只要用线性筛找出
U
\sqrt{U}
U范围内的所有素数,然后对每一个素数在[L,U]范围内的合数打标记mp,最后遍历标记数组mp,找到minn和maxx即可。
LL v[maxn],prime[maxn];//v存质数,vis判断是不是质数
bool mp[maxn];
int primes(LL n){
int m=0;
for(LL i=2;i<=n;i++){
if(v[i]==0){//i是质数
v[i]=i;prime[++m]=i;
}
for(int j=1;j<=m;j++){
if(prime[j]>v[i]||prime[j]>n/i)break;
v[i*prime[j]]=prime[j];
}
}
return m;
}
int main(){
LL l,u,minn,maxx,c1,c2,d1,d2,pre,sum;
int co=primes(sqrt(2147483647)),tt;
while(scanf("%lld%lld",&l,&u)!=EOF){
minn=1e9+10;maxx=-1;
sum=u-l+1;
memset(mp,0,sizeof mp);
if(l==1){
mp[1]=1;sum--;
}
for(LL i=1;prime[i]<=sqrt(u);i++){
if(!prime[i])break;
LL j=max(2ll,l/prime[i]+(l%prime[i]!=0));
while(j*prime[i]<=u){
if(!mp[j*prime[i]-l+1])sum--;
mp[j*prime[i]-l+1]=true;
j++;
}
}
if(sum<2){
printf("There are no adjacent primes.\n");
continue;
}
pre=0;
for(LL i=l;i<=u;i++){
if(!mp[i-l+1]){
if(pre!=0){
if(minn>i-pre){minn=i-pre;c1=pre;c2=i;}
if(maxx<i-pre){maxx=i-pre;d1=pre;d2=i;}
}
pre=i;
}
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",c1,c2,d1,d2);
}
return 0;
}