zoukankan      html  css  js  c++  java
  • Pollard_rho定理 大数的因数个数 这个板子超级快

    https://nanti.jisuanke.com/t/A1413

    AC代码

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <map>
    using namespace std;
    typedef long long ll;
    const int NUM=10;//运算次数,Miller_Rabin算法为概率运算,误判率为2^(-NUM);
    ll t,f[100];
    ll mul_mod(ll a,ll b,ll n)//求a*b%n,由于a和b太大,需要用进位乘法
    {
        a=a%n;
        b=b%n;
        ll s=0;
        while(b)
        {
            if(b&1)
                s=(s+a)%n;
            a=(a<<1)%n;
            b=b>>1;
        }
        return s;
    }
    ll pow_mod(ll a,ll b,ll n)//求a^b%n
    {
        a=a%n;
        ll s=1;
        while(b)
        {
            if(b&1)
                s=mul_mod(s,a,n);
            a=mul_mod(a,a,n);
            b=b>>1;
        }
        return s;
    }
    bool check(ll a,ll n,ll r,ll s)
    {
        ll ans,p,i;
        ans=pow_mod(a,r,n);
        p=ans;
        for(i=1;i<=s;i++)
        {
            ans=mul_mod(ans,ans,n);
            if(ans==1&&p!=1&&p!=n-1)return true;
            p=ans;
        }
        if(ans!=1)return true;
        return false;
    }
    bool Miller_Rabin(ll n)//Miller_Rabin算法,判断n是否为素数
    {
        if(n<2)return false;
        if(n==2)return true;
        if(!(n&1))return false;
        ll i,r,s,a;
        r=n-1;s=0;
        while(!(r&1)){r=r>>1;s++;}
        for(i=0;i<NUM;i++)
        {
            a=rand()%(n-1)+1;
            if(check(a,n,r,s))
                return false;
        }
        return true;
    }
    ll gcd(ll a,ll b)
    {
        return b==0?a:gcd(b,a%b);
    }
    ll Pollard_rho(ll n,ll c)//Pollard_rho算法,找出n的因子
    {
        ll i=1,j,k=2,x,y,d,p;
        x=rand()%n;
        y=x;
        while(true)
        {
            i++;
            x=(mul_mod(x,x,n)+c)%n;
            if(y==x)return n;
            if(y>x)p=y-x;
            else p=x-y;
            d=gcd(p,n);
            if(d!=1&&d!=n)return d;
            if(i==k)
            {
                y=x;
                k+=k;
            }
        }
    }
    void _find(ll n)//找出n的所有因子
    {
        if(Miller_Rabin(n))
        {
            f[t++]=n;//保存所有因子
            return;
        }
        ll p=n;
        while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);//由于p必定为合数,所以通过多次求解必定能求得答案
        _find(p);
        _find(n/p);
    }
    int main()
    {
        srand(time(NULL));//随机数设定种子
        ll n;
        while(scanf("%lld",&n)==1)
        {
            if(n == 1) {
                puts("1");
                continue;
            }
            if(Miller_Rabin(n)){
                puts("2");
                continue;
            }
            t=0;
            _find(n);
            map<ll,ll> ma;
            for(int i=0;i<t;i++)
                ma[f[i]]++;
            ll ans=1;
            for(auto it:ma)
                ans*=it.second+1;
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    [HNOI2013]切糕
    [POI2015]Kinoman
    「NOI2014」动物园
    [ZJOI2006]书架
    [HEOI2015]定价
    bzoj1833 数字计数
    bzoj2565 最长双回文子串
    bzoj4198 荷马史诗
    bzoj1193 马步距离
    bzoj3329 Xorequ
  • 原文地址:https://www.cnblogs.com/stranger-/p/10660044.html
Copyright © 2011-2022 走看看