poj2689

来源:互联网 发布:红色警戒扫矿软件 编辑:程序博客网 时间:2024/06/05 00:36

这道题就是在区间中筛选素数,直接用筛选法会爆空间,每个数单独判断是不是素数,又会爆时间,所以就用了一个优化的筛选法,先算出数据范围每个合数可能的最小素因子,这样算每个区间是就不用再重复算这个素因子了,并且也不用每个数单独判断是不是素因子了,时间不超,空间也不超了,但是严格的时间复杂度的证明不会大哭

参考链接:

http://blog.csdn.net/a601025382s/article/details/12111297

http://www.cnblogs.com/kuangbin/archive/2013/05/20/3089840.html

(感觉国庆放假比暑假更凄凉。继续龙族系列大笑

(每个人都会有些理由,可以让你豁出命去。你留着命……就是等待把它豁出去的那一 天。 ——江南 《龙族》,是要为自己喜欢的事豁出去,不是要去犯罪!!!生气

2015.10.30:

唉,叹一口气,少活10秒,不要问我怎么知道的,天机不可泄露!!!安静

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define N 1000010#define M 65540#define INF 0x3f3f3f3fbool isprime[M];int primenum[M];bool issectionprime[N];int sectionprime[N];int cou;int sectioncou;void getprime(int a,int b){    memset(issectionprime,true,sizeof(issectionprime));    for(int i=0;(long long int)primenum[i]*primenum[i]<=(long long int)b&&i<cou;i++){//printf("%d %d\n",primenum[i],i);        int l=a/primenum[i];        if(a%primenum[i]){            l++;        }        if(l==1){//注意:这里如果l=1的话,那么乘出来就是素数,而不是合数            l++;        }        for(long long int j=l;j*primenum[i]<=(long long int)b;j++){            issectionprime[j*primenum[i]-a]=false;        }    }    if(a==1){        issectionprime[0]=false;    }    sectioncou=0;    for(int i=0;i<=b-a;i++){        if(issectionprime[i]){            sectionprime[sectioncou++]=a+i;        }    }    return;}int main(){    cou=0;    memset(isprime,true,sizeof(isprime));    //isprime[1]=false;    for(int i=2;i*i<=M-1;i++){//把M写成了N,所以越界,造成primenum[0]=0        if(isprime[i]){            //primenum[cou++]=i;这句不能写里面,因为i最多遍历到i*i<=M-1,因此会造成大于sqrt(M-1)的素数没被加进primenum这个数组里            /*if(i==3917){                printf("hahaha\n");            }*/            //printf("%d %d\n",cou-1,primenum[cou-1]);            for(int j=i+i;j<M;j=j+i){                /*if(j==3917){                    printf("hahaha\n");                }*/                isprime[j]=false;            }        }    }    //printf("%d\n",primenum[0]);    for(int i=2;i<M;i++){        if(isprime[i]){            primenum[cou++]=i;        }    }    int a,b;    while(scanf("%d%d",&a,&b)!=EOF){        getprime(a,b);        int min=INF;        int minnum;        int max=-1;        int maxnum;        for(int i=0;i<sectioncou-1;i++){            //printf("%d\n",sectionprime[i]);            /*if(sectionprime[i]==2146841093||sectionprime[i]==2146841273){                printf("%d %d\n",sectionprime[i],sectionprime[i+1]);            }*/            int jg=sectionprime[i+1]-sectionprime[i];            if(jg<min){                min=jg;                minnum=i;            }            if(jg>max){                max=jg;                maxnum=i;            }        }        //printf("%d\n",sectionprime[sectioncou-1]);        if(max==-1){            printf("There are no adjacent primes.\n");        }        else{            printf("%d,%d are closest, %d,%d are most distant.\n",sectionprime[minnum],sectionprime[minnum+1],sectionprime[maxnum],sectionprime[maxnum+1]);        }    }    return 0;}


0 0
原创粉丝点击