题目描述
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;
}