zoukankan      html  css  js  c++  java
  • 素数相关问题

    判断一个数是不是素数:

    bool prime(int n)
    {
        if(n==0||n==1) return false;
        if(n==2) return true;
        for(int i=2;i<=sqrt(n);i++)
            if(n%i==0)
                return false;
        return true;
    }

    区间筛素数(区间内素数的个数):

    #include <stdio.h>
    #include <cmath>
    #include <cstring>
    const int maxn = 1000001;
    
    
    int PrimeList[maxn];
    int PrimeNum;
    bool IsNotPrime[maxn]; // IsNotPrime[i] = 1表示i + L这个数是素数.
    
    
    void SegmentPrime(int L, int U)
    {
        // 求区间[L, U]中的素数.
        int i, j;
        int SU = sqrt(1.0 * U);
        int d = U - L + 1;
        for (i = 0; i < d; i++) IsNotPrime[i] = 0; // 一开始全是素数.
        for (i = (L % 2 != 0); i < d; i += 2) IsNotPrime[i] = 1; // 把偶数的直接去掉.
        for (i = 3; i <= SU; i += 2)
        {
            if (i > L && IsNotPrime[i - L]) continue; // IsNotPrime[i - L] == 1说明i不是素数.
            j = (L / i) * i; // j为i的倍数,且最接近L的数.
            if (j < L) j += i;
            if (j == i) j += i; // i为素数,j = i说明j也是素数,所以直接 + i.
            j = j - L;
            for (; j < d; j += i) IsNotPrime[j] = 1; // 说明j不是素数(IsNotPrime[j - L] = 1).
        }
        if (L <= 1) IsNotPrime[1 - L] = 1;
        if (L <= 2) IsNotPrime[2 - L] = 0;
        PrimeNum = 0;
        for (i = 0; i < d; i++) if (!IsNotPrime[i]) PrimeList[PrimeNum++] = i + L;
    }
    int main()
    {
        int l,r;
        while(scanf("%d%d",&l,&r)==2)
        {
            SegmentPrime(l,r);
            printf("%d
    ",PrimeNum);
        }
        return 0;
    }

    区间筛素数(区间内相邻的差最小和最大的素数)

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int maxn=1e6;
    int prime[maxn+10];
    
    void getPrime()
    {
        memset(prime,0,sizeof(prime));
        for(int i=2;i<=maxn;i++)
        {
            if(!prime[i])
                prime[++prime[0]]=i;
            for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++)
            {
                prime[prime[j]*i]=1;
                if(i%prime[j]==0)
                    break;
            }
        }
    }
    bool isprime[maxn+10];
    int prime2[maxn+10];
    void getPrime2(int L,int R)
    {
        memset(isprime,1,sizeof(isprime));
        if(L<2) L=2;
        for(int i=1;i<=prime[0]&&(long long)prime[i]*prime[i]<=R;i++)
        {
            int s=L/prime[i]+(L%prime[i]>0);
            if(s==1)
                s=2;
            for(int j=s;(long long)j*prime[i]<=R;j++)
                if((long long)j*prime[i]>=L)
                isprime[j*prime[i]-L]=false; 
        }
        prime2[0]=0;
        for(int i=0;i<=R-L;i++)
            if(isprime[i])
            prime2[++prime2[0]]=i+L;
    }
    int main()
    {
        getPrime();
        int L,R;
        while(scanf("%d%d",&L,&R)!=EOF)
        {
            getPrime2(L,R);
            if(prime2[0]<2)
                printf("There are no adjacent primes.
    ");
            else
            {
                int x1=0,x2=1000000,y1=0,y2=0;
                for(int i=1;i<prime2[0];i++)
                {
                    if(prime2[i+1]-prime2[i]<x2-x1)
                    {
                        x1=prime2[i];
                        x2=prime2[i+1];
                    }
                    if(prime2[i+1]-prime2[i]>y2-y1)
                    {
                        y1=prime2[i];
                        y2=prime2[i+1];
                    }
                }
                printf("%d,%d are closest, %d,%d are most distant.
    ",x1,x2,y1,y2);
            }
        }
        return 0;
    }

     素数测试,若不是素数,输出它的最小素因子:

    //写得太好了,每一个函数都是一个模版呀~~~~
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define gcc 10007
    #define MAX ((INT)1<<63)-1
    
    using namespace std;
    
    typedef unsigned long long INT;
    INT p[10]={2,3,5,7,11,13,17,19,23,29};
    inline INT gcd(INT a,INT b)
    {
        INT m=1;
        if(!b)    return a;
        while(m)
        {
            m=a%b;
            a=b;
            b=m;
        }
        return a;
    }
    
    //计算a*b%n
    
    inline INT multi_mod(INT a,INT b,INT mod)
    {
        INT sum=0;
        while(b)
        {
            if(b&1)    sum=(sum+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return sum;
    }
    
    //计算a^b%n;
    
    inline INT quickmod(INT a,INT b,INT mod)
    {
        INT sum=1;
        while(b)
        {
            if(b&1)    sum=multi_mod(sum,a,mod);
            a=multi_mod(a,a,mod);
            b>>=1;
        }
        return sum;
    }
    
    bool miller_rabin(INT n)
    {
        int i,j,k=0;
        INT u,m,buf;
        //将n分解为m*2^k
        if(n==2)
            return true;
        if(n<2||!(n&1))
            return false;
        m=n-1;
        while(!(m&1))
            k++,m>>=1;
        for(i=0;i<9;i++)
        {
            if(p[i]>=n)
                return true;
            u=quickmod(p[i],m,n);
            if(u==1)
                continue;
            for(j=0;j<k;j++)
            {
                buf=multi_mod(u,u,n);
                if(buf==1&&u!=1&&u!=n-1)
                    return false;
                u=buf;
            }
            //如果p[i]^(n-1)%n!=1那么n为合数
            if(u-1)
                return false;
        }
        return true;
    }
    
    //寻找n的一个因子,该因子并不一定是最小的,所以下面要二分查找最小的那个因子
    INT pollard(INT n)
    {
        INT i=1;
        INT x=rand()%(n-1)+1;
        INT y=x;
        INT k=2;
        INT d;
        do
        {
            i++;
            d=gcd(n+y-x,n);
            if(d>1&&d<n)
                return d;
            if(i==k)
                y=x,k*=2;
            x=(multi_mod(x,x,n)+n-gcc)%n;
        }while(y!=x);
        return n;
    }
    
    INT MIN;
    
    INT pollard_min(INT n)
    {
        INT p,a,b=MAX;
        if(n==1)    return MAX;
        if(miller_rabin(n))    return n;
        p=pollard(n);
        a=pollard_min(p);//二分查找
        INT y=n/p;
        b=pollard_min(y);
        return a<b?a:b;
    }
    
    int main(void)
    {
        INT T;
        INT n;
        scanf("%lld",&T);
        while(T--)
        {
            scanf("%lld",&n);
            MIN=MAX;
            if(miller_rabin(n))
            {
                puts("Prime");
            }
            else printf("%lld
    ",pollard_min(n));
        }
        return 0;
    }
  • 相关阅读:
    MS SQL Server备份与恢复实例
    如何加快查询,优化数据库
    使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引
    URL重写可删节日期模式正则表达式之强力应用
    索引全攻略
    大数据量分页存储过程效率测试附代码
    形成查询结果(实体框架) 使用导航属性导航关系
    C#开源资源大汇总
    大数据量的系统的数据库结构如何设计?
    数据库查询优化
  • 原文地址:https://www.cnblogs.com/scottding/p/4333998.html
Copyright © 2011-2022 走看看