欧拉(线性)筛 && Miller_Rabin 测试素数

void make_prime()//欧拉筛
{
    is_prime[1]=is_prime[0]=true;
    for(int i=2;i<=1e6;i++)
    {
        if(!is_prime[i])
        {
            prime[++tot]=i;
        }
        for(int j=1;j<=tot&&i*prime[j]<=1e6;j++)
        {
            is_prime[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                break;
            }
        }
    }
}

Miller_Rabin 测试素数:https://www.cnblogs.com/Norlan/p/5350243.html

模板:https://cn.vjudge.net/problem/HihoCoder-1287

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>

#define mem(a,b) memset(a,b,sizeof(a))
#define int long long

using namespace std;

const int maxn=1e8+10;
//10000000

int mul(int a,int b,int mod)
{
    int s=0;
    while(b)
    {
        if(b&1) s=(s+a)%mod;
        a=(a*2)%mod;
        b>>=1;
    }
    return s;
}

int smul(int a,int b,int mod)
{
    int s=1;
    while(b)
    {
        if(b&1) s=mul(s,a,mod);
        a=mul(a,a,mod);
        b>>=1;
    }
    return s;
}

int make_prime[15]={0,2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};//底数

int Miller_Rabin(int p)
{
    int is_p=1;
    if(p==1) return 0;
    for(int i=1;i<=12;i++)//保证a与底数互质特判
    {
        if(!(p%make_prime[i])) return 0;
        if(p==make_prime[i]) return 1;
    }
    for(int i=1;i<=12;i++)
    {
        int now=p-1,s;
        while((s=smul(make_prime[i],now,p))==1)//a^(p-1)=1(%p);
        {
            if(!(now%2))//每次去除2的因子知道没有2为止
                now/=2;
            else
                break;
        }
        if(s==1||s==p-1) continue;//若s==1||p-1通过测试
        is_p=0;break;
    }
    return is_p;
}

#undef int
int main(){
#define int long long
    int a,t;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld",&a);
        printf("%s\n",(Miller_Rabin(a)?"Yes":"No"));
    }
    return 0;
}

 

posted @ 2019-02-28 21:15  Minun  阅读(144)  评论(0编辑  收藏  举报