codeforces 837E 数论

来源:互联网 发布:ti84 app mac 编辑:程序博客网 时间:2024/05/03 22:13

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 aand 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).

Example
Input
3 5
Output
3
Input
6 3
Output

1




题意:定义F(a,0) = 0,F(a,b) = 1 + F(a,b - GCD(a,b)。给定 x 和 y (<=1e12)求F(x,y)。


假设 a=A*gcd b=B*gcd 一轮后 A*gcd,(B-1)*gcd 当(B-k)%T == 0时 gcd变化 T为A的因子,由于因子数量很多,所以我们利用质因子来处理因子的问题,要找到最小的k,其实就是找最小的B%T ,这个想想就懂了,然后找到这个乘到gcd里面的因子,这个因子将会是 所有y%T==0 的质因子组成,把这些质因子挑出来,其实就相当于找到了这个因子,并从y中剔除。



#include <bits/stdc++.h>using namespace std;typedef long long ll;vector<ll> v;int main(){    ll x,y;    scanf("%lld%lld",&x,&y);    ll tt=__gcd(x,y);    x/=tt,y/=tt;    for(ll i=2;i*i<=x;i++)    {        while(x%i==0)        {            x/=i;            v.push_back(i);        }    }    if(x>1) v.push_back(x);    ll ans=0;    while(y)    {        ll hh=y;        for(int i=0;i<v.size();i++)            hh=min(hh,y%v[i]);        y-=hh;        ans+=hh;        vector<ll> v1;        for(int i=0;i<v.size();i++)        {            if(y%v[i]==0)            {                y/=v[i];            }            else v1.push_back(v[i]);        }        v.swap(v1);    }    printf("%lld\n",ans );}