Educational Codeforces Round 26 E. Vasya's Function(数论)

传送门:点击打开链接

E. Vasya's Function
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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

题意是……(不可描述)……。

两个递归,如果单纯的跑数据,第三组示例都过不了,别问我为什么。所以要选择优化,可以发现,在F的计算中,每一次的递归都牵扯到gcd(a,b),那么不妨把a,b划到最简,什么算最简形式,就是互质呗,这是一个困难的过程。枚举a的因子,让b除去b中所有跟a相等的因子,然后取所偶有数的最小值,看起来很麻烦,其实只需要b%a的因子取min就可以。如果a没有任何因子,也就是a是质数时结束循环,此时要再取一次tempb跟b%a的最小值,不然第14组数据都过不去,别问我为什么。最后运行时间30ms,还可以。注意所有的数据最好都用long long。


代码实现:


#include
#include
#include
#define ll long long

using namespace std;

ll gcd(ll x,ll y)
{
	if(x==0)
	return y;
	
	return gcd(y%x,x);
}

ll find(ll x,ll y)
{
	if(y==0)
	return 0;
	
	ll temp=gcd(x,y);
	x/=temp;y/=temp;
	ll tempa=x,tempb=y;
	
	for(ll i=2;i*i<=x;i++)
	{
		if(x%i)
		continue;
		
		tempb=min(tempb,y%i);
		while(x%i==0)
		x/=i;
	}
	
	if(x!=1)
	tempb=min(tempb,y%x);
	
	return find(tempa,y-tempb)+tempb;
}

int main()
{
	ll a,b;
	while(cin>>a>>b)
	{
		ll sum=find(a,b);
		cout<


你可能感兴趣的:(******CF******,******数论******,ACM的进阶之路,CodeForce题解)