• pollard_rho例题


    (pollard\_rho) 例题

    (POJ 1811)

    题意:判断一个数是不是素数,如果是素数,输出 (Prime) 否则,输出最小的素因子。

    题解:使用 (Miller\_Rabin) 法则筛选素数,之后使用 (pollard\_rho) 进行因子分解,找到最小值。

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int MAXN = 501;
    const int TestCase = 10;
    int cnt;
    ll N;
    ll minn,mina,minb;
    ll prime[MAXN];
    ll fac[MAXN];
    ll num[MAXN];
    ll gcd(ll a,ll b){
        return b==0?a:gcd(b,a%b);
    }
    ll random(ll n){
        return (ll)((double)rand()/RAND_MAX*n+0.5);
    }
    ll multi(ll a,ll b,ll m){
        ll ret=0;
        while(b>0){
            if(b&1)ret=(ret+a)%m;
            b>>=1;
            a=(a<<1)%m;
        }
        return ret;
    }
    ll pow(ll a,ll b,ll m){
        ll ans=1;
        a%=m;
        while(b){
            if(b&1)ans=multi(ans,a,m);
            b>>=1;
            a=multi(a,a,m);
        }
        return ans;
    }
    bool Witness(ll a,ll n){
        ll m=n-1;
        int j=0;
        while(!(m&1)){
            ++j;m>>=1;
        }
        ll x=pow(a,m,n);
        if(x==1||x==n-1)return false;
        while(j--){
            x=x*x%n;
            if(x==n-1)return false;
        }
        return true;
    }
    bool miller_rabin(ll n){
        if(n<2)return false;
        if(n==2)return true;
        if(!(n&1))return false;
        for(int i=1;i<=TestCase;++i){
            ll a=random(n-2)+1;
            if(Witness(a,n))return false;
        }
        return true;
    }
    ll pollard_rho(ll n,int c){
        ll x,y,d,i=1,k=2;
        x=random(n-1)+1;
        y=x;
        while(true){
            ++i;
            x=(multi(x,x,n)+c)%n;
            d=gcd(y-x,n);
            if(1<d&&d<n)return d;
            if(x==y)return n;
            if(i==k){
                y=x;
                k<<=1;
            }
        }
    }
    void find(ll n,int k){
        if(n==1)return;
        if(miller_rabin(n)){
    //        prime[++cnt]=n;
            minn=min(minn,n);
            return;
        }
        ll p=n;
        while(p>=n)
            p=pollard_rho(p,--k);
        find(p,k);
        find(n/p,k);
    }
    int main(){
        ll T;
        cin>>T;
        while(T--){
            ll N;
            cin>>N;
            if(miller_rabin(N))cout<<"Prime"<<endl;
            else {
                minn=N;
                find(N,107);
                cout<<minn<<endl;
            }
        }
        return 0;
    }
    

    (POJ 2429)

    题意:已知 (gcd(a,b))(lcm(a,b)) 求解 (a) , (b) 使得 (a+b) 最小

    题解:使用 (pollard\_rho) 进行质数分解,之后使用 (dfs) 搜索即可。

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int MAXN = 501;
    const int TestCase = 10;
    int cnt;
    ll N;
    ll prime[MAXN];
    ll fac[MAXN];
    ll num[MAXN];
    ll gcd(ll a,ll b){
        return b==0?a:gcd(b,a%b);
    }
    ll random(ll n){
        return (ll)((double)rand()/RAND_MAX*n+0.5);
    }
    ll multi(ll a,ll b,ll m){
        ll ret=0;
        while(b>0){
            if(b&1)ret=(ret+a)%m;
            b>>=1;
            a=(a<<1)%m;
        }
        return ret;
    }
    ll pow(ll a,ll b,ll m){
        ll ans=1;
        a%=m;
        while(b){
            if(b&1)ans=multi(ans,a,m);
            b>>=1;
            a=multi(a,a,m);
        }
        return ans;
    }
    bool Witness(ll a,ll n){
        ll m=n-1;
        int j=0;
        while(!(m&1)){
            ++j;m>>=1;
        }
        ll x=pow(a,m,n);
        if(x==1||x==n-1)return false;
        while(j--){
            x=x*x%n;
            if(x==n-1)return false;
        }
        return true;
    }
    bool miller_rabin(ll n){
        if(n<2)return false;
        if(n==2)return true;
        if(!(n&1))return false;
        for(int i=1;i<=TestCase;++i){
            ll a=random(n-2)+1;
            if(Witness(a,n))return false;
        }
        return true;
    }
    ll pollard_rho(ll n,int c){
        ll x,y,d,i=1,k=2;
        x=random(n-1)+1;
        y=x;
        while(true){
            ++i;
            x=(multi(x,x,n)+c)%n;
            d=gcd(y-x,n);
            if(1<d&&d<n)return d;
            if(x==y)return n;
            if(i==k){
                y=x;
                k<<=1;
            }
        }
    }
    void find(ll n,int k){
        if(n==1)return;
        if(miller_rabin(n)){
            prime[++cnt]=n;
            return;
        }
        ll p=n;
        while(p>=n)
            p=pollard_rho(p,--k);
        find(p,k);
        find(n/p,k);
    }
    ll minn,mina,minb;
    int len=0;
    void dfs(int id,ll tmp){
        if(id==len+1){
            if(N/tmp+tmp<minn){
                mina=tmp;
                minb=N/tmp;
                minn=mina+minb;
    
            }
            return;
        }
        dfs(id+1,tmp);
        tmp*=fac[id];
        if(tmp>=minn)return;
        dfs(id+1,tmp);
    }
    void slove(ll n,ll x){
        cnt=0;
        find(n,107);
        sort(prime+1,prime+cnt+1);
        len=0;
        fac[len]=prime[1];
        num[len]=1;
        for(int i=2;i<=cnt;++i){
            if(fac[len]==prime[i]){
                ++num[len];
            }
            else{
                fac[++len]=prime[i];
                num[len]=1;
            }
        }
        for(int i=0;i<=len;++i){
            ll tmp=1;
            for(int j=0;j<num[i];++j){
                tmp*=fac[i];
            }
            fac[i]=tmp;
        }
    //    for(int i=0;i<=len;++i)
    //        cout<<num[i]<<" "<<fac[i]<<endl;
    }
    int main(){
        ll x,y;
        while(cin>>x>>y){
            if(x==y)cout<<x<<" "<<y<<endl;
            else {
                N=y/x;
                slove(N,x);
                minn=N+1;
                mina=1;minb=N;
                dfs(0,1);
                cout<<min(mina,minb)*x<<" "<<(mina+minb-min(mina,minb))*x<<endl;
            }
        }
        return 0;
    }
    
    新赛季的开始
  • 相关阅读:
    13.困难重重
    02.Django的第一个网页
    03.Django模板
    01.Web开发之简介
    14.效率利器之多线程和线程池
    Silverlight实用窍门系列:37.Silverlight和ASP.NET相互传参的两种常用方式(QueryString,Cookie)
    Web编码规范中文乱码解决方案
    H*ber*ate Lazy属性
    Bat如何判断txt文本中第8行是否只有"符号,有则删除整行
    #每日一练 获取字典值
  • 原文地址:https://www.cnblogs.com/VagrantAC/p/12573017.html
Copyright © 2020-2023  润新知