第十六场 问题 D: GCDLCM(Pollard's rho大整数因子分解)

题目描述

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:
A B
Constraints
1 ≤ A, B ≤ 1018
Both A and B are integers.

输出

Print one integer denotes the number of X.

样例输入

3 12

样例输出

3

emmmm,公式化简以后就知道是让求(B/A)的因子有多少个。然后就是数据范围的问题了,1e18。

强行学习了一波Pollard‘s rho

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7+10;
ll Prime[6] = {2,3,5,233,331};
ll p[maxn],sum[100];
bool vis[maxn];
int cnt;
void is_Prime() // 素数筛
{
    for(int i = 2;i < maxn; i++)
    {
        if(!vis[i])
            p[cnt++] = i;
        for(int j = 0;j < cnt && p[j] * i < maxn; j++)
        {
            vis[p[j] * i] = true;
            if(i % p[j] == 0)
                break;
        }
    }
}
ll qMul(ll a,ll b,ll m) //快速乘
{
    ll ans = 0;
    while(b)
    {
        if(b & 1)
        {
            ans += a;
            ans %= m;
        }
        a += a;
        a %= m;
        b >>= 1;
    }
    return ans;
}
ll qPow(ll a,ll b,ll mod) //快速幂
{
    ll ans = 1;
    while(b)
    {
        if(b & 1)
            ans = qMul(ans,a,mod);
        b /= 2;
        a = qMul(a,a,mod);
    }
    return ans;
}
bool Miller_Rabin(ll n) //概率素性检测
{
    if(n < 2)
        return 0;
    if(n != 2 && n % 2 == 0)
        return 0;
    ll s = n - 1;
    while(!(s & 1))
        s >>= 1;
    for(int i = 0;i < 5; i++)
    {
        if(n == Prime[i])
            return 1;
        ll t = s;
        ll m = qPow(Prime[i],s,n);
        while(t != n - 1 && m != 1 && m != n - 1)
        {
            m = qMul(m,m,n);
            t <<= 1;
        }
        if(m != n - 1 && !(t & 1))
            return 0;
    }
    return 1;
}
ll Pollards_rho(ll n) //因数分解
{
    int tot = 1;
    ll ans = 1;
    for(int i = 0;p[i] * p[i] <= n && i < cnt; ++i)
    {
        if(n % p[i] == 0)
        {
            while(n % p[i] == 0)
            {
                sum[tot]++;
                n /= p[i];
            }
            tot++;
        }
        if(n == 1)
            break;
    }
    for(int i = 1;i < tot; i++)
        ans *= (sum[i] + 1);
    if(n > 1)
    {
        if(!Miller_Rabin(n))
        {
            ll tmp = sqrt(n);
            if(tmp * tmp == n)
                ans *= 3;
            else
                ans *= 4;
        }
        else
            ans *= 2;
    }
    return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    is_Prime();
    ll a,b;
    cin >> a >> b;
    if(b % a != 0)
    {
        cout << 0 << endl;
        return 0;
    }
    ll c = b / a;
    cout << Pollards_rho(c) << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiao__hei__hei/article/details/89739538