Miller_Robin素数判定和Pollard_rho质因数分解模板

来源:互联网 发布:dct算法进行图像压缩 编辑:程序博客网 时间:2024/06/05 10:22
#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<iomanip>#include<ctime>#define ull unsigned long longusing namespace std;const int lim=20;template <typename T>inline void _read(T& x){    char t=getchar();bool sign=true;    while(t<'0'||t>'9'){if(t=='-')sign=false;t=getchar();}    for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';    if(!sign)x=-x;}ull N,k,T,ph;ull ksc(ull x,ull y,ull mod){    x%=mod;y%=mod;    ull ans=0;    while(y){        if(y&1)ans=(ans+x)%mod;        x<<=1;        if(x>=mod)x%=mod;        y>>=1;    }    return ans;}ull mont(ull x,ull y,ull mod){    ull ans=1;    for(x%=mod;y;y>>=1,x=ksc(x,x,mod)){        if(y&1)ans=ksc(ans,x,mod);    }    return ans;}ull gcd(ull x,ull y){    if(x==0)return 1;    if(x<0)return gcd(-x,y);     if(y==0)return x;    else return gcd(y,x%y);}bool check(ull a,ull n,ull x,ull t){    ull i;    ull ans=mont(a,x,n);    ull last=ans;    for(i=1;i<=t;i++){        ans=ksc(ans,ans,n);        if(ans==1&&last!=1&&last!=n-1)return true;        last=ans;    }    if(ans!=1)return true;    return false;}bool miuller_rabin(ull x){    if(x<2)return false;    if(x==2||x==3)return true;    if((x&1)==0)return false;    ull temp=x-1,t=0;    while((temp&1)==0){temp>>=1;t++;}    for(int i=1;i<=lim;i++){        ull a=rand()%(x-1)+1;        if(check(a,x,temp,t))return false;    }    return true;}ull fac[105];ull Fac[105];ull JUDGE[105];ull tot=0,TOT;ull poullard(ull x,ull c){    ull i=1,k=2;    ull x0=rand()%x;    ull y=x0;    for(;;){        i++;        x0=(ksc(x0,x0,x)+c)%x;        ull d=gcd(y-x0,x);        if(d!=1&&d!=x)return d;        if(y==x0)return x;        if(i==k){y=x0;k+=k;}    }}void getfac(ull n){    if(n==1){        fac[++tot]=1;        return;    }    if(miuller_rabin(n)){        fac[++tot]=n;        return;    }    ull p=n;    while(p>=n)p=poullard(p,rand()%(n-1)+1);    getfac(p);    getfac(n/p);}ull phi(ull x){    if(x==1)return 1;    if(miuller_rabin(x))return x-1;    tot=0;    ull temp=x,i;    getfac(x);    sort(fac+1,fac+1+tot);    for(i=1;i<=tot;i++){        if(fac[i]!=fac[i-1]){            temp=(temp/fac[i])*(fac[i]-1);        }    }    return temp;}bool judge(ull x){    if(x==1){        if(N==2)return true;        else return false;    }    ull temp=mont(x,ph,N),t;    int i;    if(temp!=1)return false;    for(i=1;i<=TOT;i++){        if(mont(x,JUDGE[i],N)==1)return false;    }    return true;}ull hahaha[1005];int main(){    srand(time(NULL));    ull num,i,j,cnt=0;    bool flag=false;    cin>>N>>k;    if(N==1){        if(k==1){            cout<<"1";        }        else cout<<"-1";        return 0;    }    ph=phi(N);    tot=0;    getfac(ph);    sort(fac+1,fac+1+tot);    tot=unique(fac+1,fac+1+tot)-fac-1;    memcpy(Fac,fac,sizeof(fac));    TOT=tot;    for(i=1;i<=TOT;i++){        JUDGE[i]=ph/Fac[i];    }    if(k==1){        for(i=1;i<=min(1000ull,N-1);i++){            if(judge(i)){                cout<<i;                return 0;            }        }        cout<<"-1";        return 0;    }    for(i=1;i<=min(1000ull,N-1);i++){        if(judge(i)){            cnt++;            hahaha[cnt]=i;            flag=true;        }    }    if(!flag){        cout<<"-1";        return 0;    }    num=phi(ph);    if(num<k){        cout<<"-1";        return 0;    }    if(cnt>=k){        cout<<hahaha[k];        return 0;    }    else {        for(i=1001;;i++){            if(judge(i)){                cnt++;                if(cnt==k){                    cout<<i;                    //cout<<"time:"<<clock()-T<<endl;                    return 0;                }            }        }    }}
#include<cstdio>#include<iostream>#include<cstdlib>#include<cmath>#include<cstring>#include<queue>#include<vector>#include<algorithm>#define ULL unsigned long long using namespace std;const int maxn=10000+5,inf=0x3f3f3f3f;ULL n,m,k,phin,A[maxn],P[maxn];inline ULL Mul(ULL A,ULL B,ULL M){    ULL ans= 0;    A%=M; B%=M;    while(B){        if(B&1)ans+=A;        if(ans>=M) ans-=M;        B>>=1;        A=A+A; if(A>=M)A-=M;    }    return ans;}inline ULL pow_mod(ULL x,ULL y, ULL M){    ULL ans=1;    for(x%=M;y;y>>=1,x=Mul(x,x,M))        if(y&1) ans=Mul(ans,x,M);    return ans;}inline ULL GCD(ULL A,ULL B){    return B>0? GCD(B,A%B):A;}const int S=20;inline bool Miller_Robin(ULL n){ //返回n是否为素数     int i,j;    if(n==2) return true;    if(!(n&1)) return false;    if(n<=1) return false;     ULL t=0,x,y,N=n-1;    while(!(N&1)) t++,N>>=1;    for(i=0;i<S;i++){        ULL a= rand()%(n-1)+1;        x= pow_mod(a,N,n);        for(j=1;j<=t;j++){            y= Mul(x,x,n);            if(y==1&&x!=1&&x!=n-1) return false;            x=y;        }        if(x!=1) return false;    }    return true;}ULL Pollard_rho(ULL x,ULL c){    ULL i=1,k=2;    ULL x0=rand()%x;    ULL y=x0;    for(;;){        i++;        x0=(Mul(x0,x0,x)+c)%x;        ULL d=GCD(y-x0,x);        if(d!=1&&d!=x)return d;        if(y==x0)return x;        if(i==k){y=x0;k+=k;}    }}int rear;void Divide(ULL n,ULL P[]){    if(n==1){        P[++rear]= 1;        return;     }    if(Miller_Robin(n)){        P[++rear]=n;        return ;    }    ULL p=n;    while(p>=n) p= Pollard_rho(p,rand()+1);    Divide(p,P); Divide(n/p,P);}int Factors(ULL n,ULL P[]){    rear=0;    Divide(n,P);    sort(P+1,P+1+rear);    return unique(P+1,P+1+rear)-P-1;}ULL Phi(ULL n){    int m=Factors(n,A);    ULL phi= n;    for(int i=1;i<=m;i++)        phi= phi/A[i]*(A[i]-1);    return phi;}inline bool IsRoot(ULL x){    if(x==1) return n==2;    if(pow_mod(x,phin,n)!=1) return false;    for(int i=1;i<=m;i++)        if(pow_mod(x,P[i],n)==1) return false;    return true;}int main(){    //freopen("data.in","r",stdin);    //freopen("myans.out","w",stdout);    srand(156546);    cin>>n>>k;    if(n==1||n==2){        if(k==1) cout<<1<<endl;        else puts("-1");        return 0;    }     phin= Phi(n);    if(k>Phi(phin)){        puts("-1");         return 0;    }    int j,cnt=0;    m=Factors(phin,P);    ULL i;    for(i=1;i<=m;i++)P[i]= phin/P[i];    for(i=1;;i++){        if(IsRoot(i)) cnt++;        if(cnt==k){            cout<<i<<endl;            return 0;        }        if(i>1024 && cnt==0){            puts("-1");            return 0;        }    }    return 0;}
0 0
原创粉丝点击