zoukankan      html  css  js  c++  java
  • Pollard Rho (大数分解算法)

    RhoPollard Rho是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:MillerRabinMillerRabin素数测试。

    Pollard_rho算法的大致流程是 先判断当前数是否是素数(Miller_rabin)了,如果是则直接返回。如果不是素数的话,试图找到当前数的一个因子(可以不是质因子)。然后递归对该因子和约去这个因子的另一个因子进行分解。

    https://lunatic.blog.csdn.net/article/details/104218095

    https://blog.csdn.net/maxichu/article/details/45459533

    #include<bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string.h>
    #include <vector>
    typedef long long ll ;
    #define int ll
    #define mod 1000000007
    #define gcd __gcd
    #define rep(i , j , n) for(int i = j ; i <= n ; i++)
    #define red(i , n , j)  for(int i = n ; i >= j ; i--)
    #define ME(x , y) memset(x , y , sizeof(x))
    //ll lcm(ll a , ll b){return a*b/gcd(a,b);}
    ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;}
    //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;}
    //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len}
    #define SC scanf
    #define INF  0x3f3f3f3f
    #define PI acos(-1)
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    using namespace std;
    const int N = 1e6+100;
    const int maxn = 2e5+9;
    int pr;
    
    int quickmul(int a , int b , int m){
        return  ((a * b - (ll)(long double)(a/m*b) * m)+m)%m ;
    }
    
    int quickpow(int a , int b , int m){
        int ans = 1 ;
        while(b){
            if(b&1) ans = quickmul(ans , a , m) ;
            b >>= 1 ;
            a = quickmul(a , a , m);
        }
        return ans ;
    }
    inline ll gcd(ll a, ll b)
    { //听说二进制算法特快
        if (!a)
            return b;
        if (!b)
            return a;
        int t = __builtin_ctzll(a | b);
        a >>= __builtin_ctzll(a);
        do
        {
            b >>= __builtin_ctzll(b);
            if (a > b)
            {
                ll t = b;
                b = a, a = t;
            }
            b -= a;
        } while (b);
        return a << t;
    }
    
    bool Miller_Rabin(int n){
        if(n == 46856248255981ll || n < 2) return false;
        if(n == 2 || n == 3 || n == 7 || n == 61 || n == 24251) return true;
        if(!(n&1) || !(n%3) || !(n%61) || !(n%24251)) return false;
        int m = n - 1 , k = 0 ;
        while(!(m&1)) k++ , m>>=1 ;// 分解2^s * t = n - 1
        rep(i , 1 , 20){
            int a = rand() % (n - 1) + 1 , x =  quickpow(a , m , n) , y;
            rep(j , 1 , k){
                y = quickmul(x , x , n);
                if(y == 1 && x != 1 && x != n - 1) return false;//二次测探
                x = y ;
            }
            if(y != 1) return false;//费马小定理
        }
        return true;
    }
    ll Pollard_Rho(ll x)
    {
        ll n = 0, m = 0, t = 1, q = 1, c = rand() % (x - 1) + 1;
        for (ll k = 2;; k <<= 1, m = n, q = 1)
        {
            for (ll i = 1; i <= k; ++i)
            {
                n = (quickmul(n, n, x) + c) % x;
                q = quickmul(q, abs(m - n), x);
            }
            t = gcd(x, q);
            if (t > 1)
                return t;
        }
    }
    map<long long, int> m;
    void fid(ll n)
    {
        if (n == 1)
            return;
        if (Miller_Rabin(n))
        {
            pr = max(pr, n);
            m[n]++;
            return;
        }
        ll p = n;
        while (p >= n)
            p = Pollard_Rho(p);
        fid(p);
        fid(n / p);
    }
    
    
    void solve(){
        int n ;
        m.clear();
        scanf("%lld", &n);
        pr = 0;
        fid(n);
        if (pr == n)
            puts("Prime");
        else{
            printf("%lld
    ", pr);
            for (map<long long, int>::iterator c = m.begin(); c != m.end();){
                printf("%lld^%d", c->first, c->second);
                if ((++c) != m.end())
                    printf(" * ");
            }
            printf("
    ");
        }
    }
    
    signed main()
    {
        //ios::sync_with_stdio(false);
        //cin.tie(0); cout.tie(0);
        int t ;
        cin >> t ;
        while(t--){
            solve();
        }
    }
    
  • 相关阅读:
    笔记44 Hibernate快速入门(一)
    tomcat 启用https协议
    笔记43 Spring Security简介
    笔记43 Spring Web Flow——订购披萨应用详解
    笔记42 Spring Web Flow——Demo(2)
    笔记41 Spring Web Flow——Demo
    Perfect Squares
    Factorial Trailing Zeroes
    Excel Sheet Column Title
    Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/nonames/p/12431202.html
Copyright © 2011-2022 走看看