zoukankan      html  css  js  c++  java
  • upc组队赛16 GCDLCM 【Pollard_Rho大数质因数分解】

    GCDLCM

    题目链接

    题目描述

    In FZU ACM team, BroterJ and Silchen are good friends, and they often play some interesting games.
    One day they play a game about GCD and LCM. firstly BrotherJ writes an integer A and Silchen writes an integer B on the paper. Then BrotherJ gives Silchen an integer X. Silchen will win if he can find two integers Y1 and Y2 that satisfy the following conditions:
    • GCD(X, Y1) = A
    • LCM(X, Y2) = B
    • Fuction GCD(X, Y ) means greatest common divisor between X and Y .
    • Fuction LCM(X, Y ) means lowest common multiple between X and Y .
    BrotherJ loves Silchen so much that he wants Silchen to win the game. Now he wants to calculate how many number of X he can give to Silchen.

    输入

    Input is given from Standard Input in the following format:

    输出

    Print one integer denotes the number of X.

    样例输入

    3
    12
    

    样例输出

    3
    

    题解

    大数质因数分解 Pollard_Rho

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define scac(x) scanf("%c",&x)
    #define sca(x) scanf("%d",&x)
    #define sca2(x,y) scanf("%d%d",&x,&y)
    #define sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define scl(x) scanf("%lld",&x)
    #define scl2(x,y) scanf("%lld%lld",&x,&y)
    #define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
    #define pri(x) printf("%d
    ",x)
    #define pri2(x,y) printf("%d %d
    ",x,y)
    #define pri3(x,y,z) printf("%d %d %d
    ",x,y,z)
    #define prl(x) printf("%lld
    ",x)
    #define prl2(x,y) printf("%lld %lld
    ",x,y)
    #define prl3(x,y,z) printf("%lld %lld %lld
    ",x,y,z)
    #define mst(x,y) memset(x,y,sizeof(x))
    #define ll long long
    #define LL long long
    #define pb push_back
    #define mp make_pair
    #define P pair<double,double>
    #define PLL pair<ll,ll>
    #define PI acos(1.0)
    #define eps 1e-6
    #define inf 1e17
    #define mod 1e9+7
    #define INF 0x3f3f3f3f
    #define N 1005
    const int maxn = 10005;
    typedef unsigned long long ULL;
    LL Fac[1000];
    int Fn;
    const int P_TEST[7]={2,3,5,7,11,13,17};
    const int RhoLimit=10000;
    const int RhoC=13;
    LL GetPow(LL x,LL k,LL MOD);
    LL gcd(LL x,LL y);
    bool Miller_Rabin(LL x);
    LL Pollard_Rho(LL n);
    void Work(LL n);
    LL Random(LL x);
    LL QMMul(LL x,LL y,LL MOD);
    LL GetPow(LL x,LL k,LL MOD)
    {
      LL ans=1;
      for (;k>0;k>>=1,x=QMMul(x,x,MOD))
      if (k&1) ans=QMMul(ans,x,MOD);
      return ans;
    }
    bool Miller_Rabin(LL x)
    {
      if (x==2) return 1;
      if (x<=1 || x&1==0) return 0;
      for (int i=0;i<7 && P_TEST[i]<x;++i)
      {
        LL y=x-1;
        while ((y&1)==0) y>>=1;
        LL t=GetPow(P_TEST[i],y,x);
        while (y!=x-1 && t!=1 && t!=x-1)
        {
          t=QMMul(t,t,x);
          y<<=1;
        }
        if (!(t==x-1 || (y&1) && t==1)) return 0;
      }
      return 1;
    }
    LL Pollard_Rho(LL n)
    {
      LL x=Random(n-2)+2;
      LL y=x;
      int STEP=2;
      for (int i=1;;++i)
      {
        x=QMMul(x,x,n)+RhoC;
        if (x>=n) x-=n;
        if (x==y) return -1;
        LL d=gcd(abs(x-y),n);
        if (d>1) return d;
        if (i==STEP)
        {
          i=0;
          y=x;
          STEP<<=1;
        }
      }
    }
    void Work(LL n)
    {
      if (Miller_Rabin(n)) {Fac[Fn++]=n;return;}
      LL p;
      for (int i=0;i!=RhoLimit;++i)
      {
        p=Pollard_Rho(n);
        if (p!=-1) break;
      }
      if (p==-1) return;
      Work(p);
      Work(n/p);
    }
    LL Random(LL x)
    {
      unsigned long long p=rand()*rand();
      p*=rand()*rand();p+=rand();
      return p%x;
    }
    LL gcd(LL x,LL y)
    {
      if (y==0) return x;
      return gcd(y,x%y);
    }
    LL QMMul(LL x,LL y,LL MOD)
    {
      LL ans=0;
      for (;y>0;y>>=1)
      {
        if (y&1)
        {
          ans+=x;
          if (ans>=MOD) ans-=MOD;
        }
        x+=x;
        if (x>=MOD) x-=MOD;
      }
      return ans;
    }
     
     
    int main()
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        if(b%a)
          {
            printf("0
    ");
            return 0;
          }
        ll xxx = b/a;
        if(xxx == 1)
          {
            printf("1
    ");
            return 0;
          }
        Work(xxx);
        sort(Fac+0,Fac+Fn);
        ll cnt = 1;
        ll temp = Fac[0];
        ll res = 1;
        for (int i=1;i<Fn;++i)
        {
          if(temp != Fac[i])
          {
            res*=(cnt+1);
            cnt = 1;
            temp = Fac[i];
            //cout<<cnt<<endl;
          }
          else
          {
            cnt++;
          }
        }
        res *= (cnt+1);
        prl(res);
        return 0;
    }
    
  • 相关阅读:
    截取字符串时长度的问题
    《Asp.Net 2.0 揭秘》读书笔记(三)
    gmail的相关参数
    《Asp.Net 2.0 揭秘》读书笔记(四)
    《Asp.Net 2.0 揭秘》读书笔记(五)
    《Asp.Net 2.0 揭秘》读书笔记(一)
    今夜,我又坐在电脑面前想你
    如果你是一名经理,你必须履行经理的四项职责
    向明月买醉
    想找个人真心真意过一生
  • 原文地址:https://www.cnblogs.com/llke/p/10809776.html
Copyright © 2011-2022 走看看