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\n",x)
#define pri2(x,y) printf("%d %d\n",x,y)
#define pri3(x,y,z) printf("%d %d %d\n",x,y,z)
#define prl(x) printf("%lld\n",x)
#define prl2(x,y) printf("%lld %lld\n",x,y)
#define prl3(x,y,z) printf("%lld %lld %lld\n",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\n");
        return 0;
      }
    ll xxx = b/a;
    if(xxx == 1)
      {
        printf("1\n");
        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;
}
posted @ 2019-05-04 21:01  llke  阅读(233)  评论(0编辑  收藏  举报