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<iostream>
#include<algorithm>
#include<cmath>
#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<<sum<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值