• 大数分解


    const int S=8;//随机算法判定次数一般8~10就够了
    //计算 ret=(a*b)%c    a,b,c<2^63 
    ll mult_mod(ll a,ll b,ll c)
    {
        a%=c;
        b%=c;
        ll ret=0;
        ll tmp=a;
        while(b)
        {
            if(b&1) 
            {
                ret+=tmp;
                if(ret>c) ret-=c;//直接取模慢很多 
            }
            tmp<<=1;
            if(tmp>c) tmp-=c;
            b>>=1;
        }
        return ret;
    } 
    //计算ret=(a^n)%mod
    ll pow_mod(ll a,ll n,ll mod)
    {
        ll ret=1;
        ll temp=a%mod;
        while(n)
        {
            if(n&1) ret=mult_mod(ret,temp,mod);
            temp=mult_mod(temp,temp,mod);
            n>>=1;
        }
        return ret;
    }
    //通过a^n(n-1)=1(mod n)来判断 n 是不是素数 
    //n-1=x * 2^t 中间使用二次判断 
    //是合数返回true ,不一定是合数返回false 
    bool check(ll a,ll n,ll x,ll t)
    {
        ll ret=pow_mod(a,x,n);
        ll last=ret;
        for(int i=1;i<=t;i++)
        {
            ret=mult_mod(ret,ret,n);
            if(ret==1&&last!=1&&last!=n-1) return true;
            last=ret;
        }
        if(ret!=1) return true;
        else return false;
    }
    // Miller_Rabin算法进行素数测试
    //速度快可以判断一个 < 2^63 的数是不是素数
    //是素数返回true,(可能是伪素数)
    //不是素数返回false 
    bool Miller_Rabin(ll n)
    {
        if(n<2) return false;
        if(n==2) return true;
        if((n&1)==0) return false;//偶数 
        ll x=n-1;
        ll t=0;
        while((x&1)==0) 
        {
            x>>=1;
            t++;
        }
        srand(time(NULL));
        for(int i=0;i<S;i++)
        {
            ll a=rand()%(n-1)+1;
            if(check(a,n,x,t)) return false;
        }
        return true;
    } 
    // pollard_rho算法进行质因素分解 
    vector<ll>factor;//质因数分解结果 (刚返回时是无序的)
    //int tol;//质因数的个数 编号0~tol-1; 
    ll gcd(ll a,ll b)
    {
        ll t;
        while(b)
        {
            t=a;
            a=b;
            b=t%b;
        }
        if(a>=0) return a;
        else return -a;
    }
    //找出一个因子
    ll pollard_rho(ll x,ll c)
    {
        ll j=1,k=2;
        srand(time(NULL));
        ll x0=rand()%(x-1)+1;
        ll y=x0;
        while(1)
        {
            j++;
            x0=(mult_mod(x0,x0,x)+c)%x;
            ll d=gcd(y-x0,x);
            if(d!=1&&d!=x) return d;
            if(y==x0) return x;
            if(j==k) 
            {
                y=x0;
                k+=k;
            }
        } 
    } 
    //对n进行素因子分解,存入vector,k设置为107左右即可
    void findfac(ll n,int k)
    {
        if(n==1) return ;
        if(Miller_Rabin(n))
        {
            factor.push_back(n);
            return ;
        }
        ll p=n;
        int c=k;
        while(p>=n) p=pollard_rho(p,c--);
        findfac(p,k);
        findfac(n/p,k);
    } 
    void solve(){
        factor.clear();
        ll n;
        cin>>n;
        findfac(n,107);
        ll te=1;
        for(auto i:factor){
            te*=i;
        }
        if(te==n){
            cout<<"no"<<endl;
        }
        else{
            cout<<"yes"<<endl;
        }
    }
    rush!
  • 相关阅读:
    mitmproxy抓包工具
    java基础|int和Integer的区别
    Vue|退出功能
    Vue|分页处理
    apt-get本地软件源搭建
    rqt_plot报错
    创建ROS 工作空间时出现:程序“catkin_init_workspace”尚未安装,程序“catkin_make”尚未安装。
    ubuntu16.04安装ROS
    debian及Ubuntu各版本下载地址获取
    解决sudo rosdep init和rosdep update的错误
  • 原文地址:https://www.cnblogs.com/LH2000/p/15541928.html
Copyright © 2020-2023  润新知