zoukankan      html  css  js  c++  java
  • bzoj3667: RabinMiller算法

    3667: Rabin-Miller算法

    Input

    第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数。你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime 
    第二,如果不是质数,输出它最大的质因子是哪个。 
    

    Output

    第一行CAS(CAS<=350,代表测试数据的组数) 
    以下CAS行:每行一个数字,保证是在64位长整形范围内的正数。 
    对于每组测试数据:输出Prime,代表它是质数,或者输出它最大的质因子,代表它是和数 
    

    Miller Rabin和pollard rho模板题

    卡常卡好久,最后把快速(慢速)乘改成long double才过的

    #include<bits/stdc++.h>
    using namespace std;
    #define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
    #define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
    typedef unsigned long long ll;
    inline int read(){
        int x;
        char c;
        int f=1;
        while((c=getchar())!='-' && (c<'0' || c>'9'));
        if(c=='-') c=getchar(),f=-1;
        x=c^'0';
        while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
        return x*f;
    }
    inline ll readll(){
        ll x;
        char c;
        ll f=1;
        while((c=getchar())!='-' && (c<'0' || c>'9'));
        if(c=='-') c=getchar(),f=-1;
        x=c^'0';
        while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
        return x*f;
    }
    const int Times=5;
    inline bool chkmax(ll &x,ll y){return (y>x)?(x=y,1):0;}
    int a[4]={2,3,5,7};
    ll randll(ll l,ll r){
        ll mod=(r-l+1);
        return 1ll*rand()%mod*rand()%mod+l;
    }
    ll work(ll x,ll y,ll mod){
        if(y>x) return x+mod-y;
        return x-y;
    }
    ll mul(ll x,ll y,ll mod){
        return work(x*y,(ll)((long double)x/mod*y+1e-8)*mod,mod);
    }
    ll ksm(ll x,ll y,ll mod){
        ll res=1;
        while(y){
            if(y&1ll) res=mul(res,x,mod);
            x=mul(x,x,mod);
            y>>=1ll;
        }
        return res;
    }
    bool miller_rabin(ll n){
        if(n==1 || (n>3 && n%6!=1 && n%6!=5)) return 0;
        REP(i,0,3){
            if(n==a[i]) return 1;
            if(n%a[i]==0) return 0;
        }
        ll u=n-1,cnt=0;
        while(!(u&1ll)) u>>=1ll,++cnt;
        int T=Times;
        while(T--){
            ll x=randll(2,n-1);
            ll y=ksm(x,u,n),lst;
            REP(i,1,cnt){
                lst=y,y=mul(y,y,n);
                if(y==1 && lst!=1 && lst!=n-1) return 0;
            }
            if(y!=1) return 0;
        }
        return 1;
    }
    ll Max;
    ll gcd(ll x,ll y){
        if(!y) return x;
        return gcd(y,x%y);
    }
    inline ll Abs(ll x,ll y){
        if(y>x) return y-x;
        return x-y;
    }
    ll pollard_rho(ll n,ll c){
        ll x=rand()%n,y=x,p=1,k=2;
        for(ll i=1;p==1;++i){
            x=(mul(x,x,n)+c)%n;
            p=gcd(Abs(x,y),n);
            if(i==k) k<<=1ll,y=x;
        }
        return p;
    }
    void find(ll n){
        if(n==1) return;
        if(miller_rabin(n)){
            chkmax(Max,n);
            return;
        }
        ll x=n,c=0;
        while(x==n && c<=n) x=pollard_rho(n,++c);
        find(x),find(n/x);
    }
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("pollard.in","r",stdin);
        freopen("pollard.out","w",stdout);
    #endif
        srand(2523452);
        int T=read();
        while(T--){
            ll x=readll();Max=0;
            find(x);
            if(Max==x) printf("Prime\n");
            else printf("%llu\n",Max);
        }
        return 0;
    }
    
    
  • 相关阅读:
    vmware 搭建内外网分开的三台centos7.9虚拟机
    CentOS 7 搭建frp内网穿透服务端
    CentOS 7 搭建frp内网穿透客户端
    Redis设计与实现读书笔记
    easyui 下拉框绑定成功之后,又无法显示
    easyui 实现后一个弹框向前一个弹框传值
    学会这七个Python GUI图形界面化库,就没有做不出来的界面!超有用!
    最新!用Python免费连接附近WiFi教程!没有我蹭不到的网!
    用Python实现九九乘法表的几种方式,入门必备案例!超级简单!
    为了每天准时看到冰冰,我用Python写了个自动提醒脚本,美滋滋!
  • 原文地址:https://www.cnblogs.com/zhou888/p/8476732.html
Copyright © 2011-2022 走看看