您的位置:首页 > 其它

Codeforces 837E Vasya's Function - 数论

2017-08-05 16:49 295 查看
Vasya is studying number theory. He has denoted a function f(a, b) such that:

f(a, 0) = 0;

f(a, b) = 1 + f(a, b - gcd(a, b)), where gcd(a, b) is the greatest common divisor of a and b.

Vasya has two numbers x and y, and he wants to calculate f(x, y). He tried to do it by himself, but found out that calculating this function the way he wants to do that might take very long time. So he decided to ask you to implement a program that will calculate this function swiftly.

Input
The first line contains two integer numbers x and y (1 ≤ x, y ≤ 1012).

Output
Print f(x, y).

Examples

Input
3 5


Output
3


Input
6 3


Output
1


  题目大意 (题目太简洁,不需要大意)

  因为

,所以最终一定会到达边界情况。

  所以我们考虑如果a,b的gcd不为1,那么f(a, b - gcd(a, b))在干的事情相当于把b表示成gcd(a, b) * x的形式,每次递归就相当于就是让x减少某个数,如果设g = gcd(a, b),那么就有f(a. b) = f(a / g, b / g)。

  如果a和b的gcd是1,那么我们考虑下一个和a不互质的数。这个数一定是a的某个质因子的倍数,所以我们根号大暴力将a质因数分解,然后for一遍,挨个计算不超过b的最大的是pi的倍数的数,然后继续上面的做法,递归求解。

  因为当gcd不为1时,至少为2,所以递归的层数不超过

层,因为a至多有log2a个不同的质因子,所以总时间复杂度为



Code

/**
* Codeforces
* Problem#837E
* Accepted
* Time: 15ms
* Memory: 2048k
*/
#include <bits/stdc++.h>
using namespace std;
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
typedef bool boolean;
#define smax(a, b) a = max(a, b)
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = 1;
while(!isdigit((x = getchar())) && x != '-' && x != -1);
if(x == -1) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -1;
}
for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
ungetc(x, stdin);
u *= aFlag;
return true;
}

#define LL long long

template<typename T>
T gcd(T a, T b) {
return (b == 0) ? (a) : (gcd(b, a % b));
}

LL a, b;

inline void init() {
readInteger(a);
readInteger(b);
LL g = gcd(a, b);
a /= g, b /= g;
}

vector<LL> fac;
void getFactor(LL x) {
fac.clear();
for(LL i = 2; i * i <= x; i++) {
if((x % i) == 0) {
while((x % i) == 0)    x /= i;
fac.push_back(i);
}
}
if(x > 1)    fac.push_back(x);
}

LL f(LL a, LL b) {
if(b <= 1)    return b;
getFactor(a);
LL near = 0, g;
for(int i = 0; i < (signed)fac.size(); i++)
smax(near, b / fac[i] * fac[i]);
g = gcd(a, near);
return b - near + f(a / g, near / g);
}

inline void solve() {
printf(Auto, f(a, b));
}

int main() {
init();
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: