day 5 【B班】wqy数论进阶

断了今生、忘了曾经 提交于 2019-11-30 18:20:15

费马小定理、欧拉定理与扩展欧拉定理 证明

Miller_Rabin素数测试

int prime[10]={2,3,5,7,11,13,17,19,23,29};


inline int ksc(int a,int k,int mod){
    int res=0;
    for(;k;k>>=1){
        if(k&1)
            res=(res+a)%mod;
        a=(a+a)%mod;
    } 
    return res;
}

inline int ksm(int a,int k,int mod){
    int res=1;
    for(;k;k>>=1){
        if(k&1)
            res=ksc(res,a,mod);
        a=ksc(a,a,mod);
    }
    return res;
}

inline bool Miller_Rabin(int n){
    int q=0,p1=n-1;//将n=2^q+p1; 
    if(n==2)return 1;//特判0,1,2,偶数(因为接下来的只适用于素数) 
    if(n<2 || !(n&1))return 0;
    while(!(p1&1)){//p1不为2就一直分解 
        q++;
        p1>>=1;
    }
    int now;
    for(int i=0;i<10 && prime[i]<n;++i){//测试质数 
        int a=prime[i];
        int last=ksm(a,p1,n);//从a^p1开始测 
        rep(j,1,q){//枚举 
            int now=ksm(last,2,n);
            if(now==1 && last!=1 && last!=n-1)//二次探测定理测试 
                return false;
            last=now;
        }
        if(last!=1)return false;//费马小定理测试 
    } 
    return true;//大概率上是一个质数  
}

#undef int
int main(){
#define int long long
    #ifdef WIN64 
    freopen("mr.txt","r",stdin);
    #endif 
    int range,n;
    rd(range),rd(n); 
    rep(i,1,n){
        int x;rd(x);
        if(Miller_Rabin(x))  
            printf("Yes\n");
        else  
            printf("No\n");
        
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!