zoukankan      html  css  js  c++  java
  • P4718 [模板]Pollard-Rho算法

    对一个大质数进行质因数分解 需要引用miller-robin来判素数

    一直写的gcd居然挂掉了... 以后用__gcd了

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define ull unsigned long long
    #define lb long double
    ll maxfac;
    
    inline ll ksc(ull x,ull y,ll p){//O(1)快速乘(防爆long long)
        return (x*y-(ull)((lb)x/p*y)*p+p)%p;
    }
    
    ll pow_mod(ll x, ll y, ll mod) {
        ll res = 1;
        while(y) {
            if(y & 1) res = ksc(res, x, mod);
            x = ksc(x, x, mod);
            y >>= 1;
        }
        return res;
    }
    
    ll ABS(ll x) {
        if(x < 0) return -x;
        return x;
    }
    
    inline bool mr(ll x,ll p){//mille rabin判质数
        if(pow_mod(x, p-1, p) != 1) return false;//费马小定理
        ll y = p - 1, z;
        while(!(y & 1)){ //二次探测
            y >>= 1;
            z = pow_mod(x, y, p);
            if(z != 1 && z != p - 1) return false;
            if(z == p - 1) return true;
        }
        return true;
    }
    
    inline bool isprime(ll x) {
        if(x < 2) return false;//mille rabin判质数
        if(x == 2 || x == 3 || x == 5 || x==7 || x == 43) return true;
        return mr(2, x) && mr(3, x) && mr(5, x) && mr(7, x) && mr(43, x);
    }
    
    inline ll rho(ll p){//求出p的非平凡因子
        ll x, y, z, c, g; int i, j;//先摆出来(z用来存(y-x)的乘积)
        while(1){//保证一定求出一个因子来
            y = x = rand() % p;//随机初始化
            z = 1; c = rand() % p;//初始化
            i = 0, j = 1;//倍增初始化
            while(++i){//开始玄学生成
                x = (ksc(x, x, p) + c) % p;//可能要用快速乘
                z = ksc(z, ABS(y - x), p);//我们将每一次的(y-x)都累乘起来
                if(x == y || !z) break;//如果跑完了环就再换一组试试(注意当z=0时,继续下去是没意义的)
                if(!(i % 127) || i == j){//我们不仅在等127次之后gcd我们还会倍增的来gcd
                    g = __gcd(z, p);
                    if(g > 1) return g;
                    if(i == j) y = x ,j <<= 1;//维护倍增正确性,并判环(一箭双雕)
                }
            }
        }
    }
    
    inline void prho(ll p) {
        if(p <= maxfac) return;
        if(isprime(p)) {
            maxfac = p;
            return;
        }
        ll pi = rho(p);//我们一次必定能求的出一个因子,所以不用while
        while(p % pi == 0) p /= pi;//记得要除尽
        prho(pi); prho(p);
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        srand(time(0));
        while(T--) {
            //srand(time(0));
            ll x;
            scanf("%lld", &x);
            maxfac = 1;
            if(isprime(x)) puts("Prime");
            else {
                prho(x);
                printf("%lld
    ", maxfac);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    User Get 'Access Denied' with Excel Service WebPart
    How To Search and Restore files from Site Collection Recycle Bin
    How To Collect ULS Log from SharePoint Farm
    How To Restart timer service on all servers in farm
    How to Operate SharePoint User Alerts with PowerShell
    How to get Timer Job History
    Synchronization Service Manager
    SharePoint 2007 Full Text Searching PowerShell and CS file content with SharePoint Search
    0x80040E14 Caused by Max Url Length bug
    SharePoint 2007 User Re-created in AD with new SID issue on MySite
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11843077.html
Copyright © 2011-2022 走看看