[2015ICPC上海] HDU5584 LCM Walk 数论

给出一个终点坐标 ( s x , s y ) (sx,sy) (sx,sy) s x ≤ 1 e 9 , s y ≤ 1 e 9 sx\leq1e9,sy\leq1e9 sx1e9,sy1e9,然后规定你可以从一点 ( x , y ) (x,y) (x,y)出发,每次可以走 ( x + l c m ( x , y ) , y ) (x+lcm(x,y),y) (x+lcm(x,y),y)或者 ( x , y + l c m ( x , y ) ) (x,y+lcm(x,y)) (x,y+lcm(x,y))两种路径,可以走 0 0 0次到若干次,求问所有合法的起点有多少个。
对于 ( x , y ) (x,y) (x,y)-> ( x + l c m ( x , y ) , y ) (x+lcm(x,y),y) (x+lcm(x,y),y),不妨设 g = g c d ( x , y ) g=gcd(x,y) g=gcd(x,y),即 ( g x ′ , g y ′ ) (gx',gy') (gx,gy)-> ( g x ′ + g x ′ y ′ , g y ′ ) (gx'+gx'y',gy') (gx+gxy,gy),显然 g x ′ + g x ′ y ′ > g y ′ gx'+gx'y'>gy' gx+gxy>gy,所以上一步一定是走到当前较大的这个。
g x ′ + g x ′ y ′ = x ′ ( g + g y ′ ) gx'+gx'y'=x'(g+gy') gx+gxy=x(g+gy),然后利用当前的逆推求出所有的解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int gcd(int x,int y) {
	if(y==0) return x;
	else return gcd(y,x%y);
}
int main() {
	int T,kase=0; 
	scanf("%d",&T);
	while(T--) {
		int a,b,ans=1;
		scanf("%d%d",&a,&b);
		while(1) {
			if(a<b) swap(a,b);
			int g=gcd(a,b);
			if(a%(g+b)) break;
			a=a/(g+b)*g;
			++ans;
		} 
		printf("Case #%d: %d\n",++kase,ans); 
	} 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值