【数论】hdu5584 LCM walk(数学推导)
2016-08-17 19:47
162 查看
题意:
从(x,y)点出发,到(x+z,y)或(x,y+z)z=lcm(x,y);给出终点(a,b),问有多少个可能起点。
题解:
注意到 gcd(x+z,y)==gcd(x,y+z)==gcd(x,y)就不难了。
从起点到终点gcd一定要相同。
设g=gcd(x,y);则x‘=y*g/(x+g) 注意令y>x;
推导过程中要用到lcm(x,y)=x*y/gcd(x,y);
判断gcd变化的条件可以用 y % (g + x) ==
0
代码如下:
还有个更简单易懂的推法:
见博客http://www.cnblogs.com/qscqesze/p/5029555.html
从(x,y)点出发,到(x+z,y)或(x,y+z)z=lcm(x,y);给出终点(a,b),问有多少个可能起点。
题解:
注意到 gcd(x+z,y)==gcd(x,y+z)==gcd(x,y)就不难了。
从起点到终点gcd一定要相同。
设g=gcd(x,y);则x‘=y*g/(x+g) 注意令y>x;
推导过程中要用到lcm(x,y)=x*y/gcd(x,y);
判断gcd变化的条件可以用 y % (g + x) ==
0
代码如下:
#include <vector> #include <map> #include <set> #include <algorithm> #include <iostream> #include <cstdio> #include <cmath> #include <cstdlib> #include <string> #include <cstring> using namespace std; long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); } int main(){ int T; cin >> T; int cas = 1; while(T--) { long long a,b,ans = 1; scanf("%lld%lld",&a,&b); if (a < b) swap(a,b); long long g = gcd(a,b); while((a % (g + b)) == 0) { a = a * g / (g + b); ans++; if (a < b) swap(a,b); } printf("Case #%d: %lld\n",cas++,ans); } return 0; }
还有个更简单易懂的推法:
见博客http://www.cnblogs.com/qscqesze/p/5029555.html
相关文章推荐
- 【HDU5584】LCM Walk(数学)
- HDU5584 LCM Walk 数学公式
- HDU5584 LCM Walk 数论
- HDU5584 LCM Walk(数学+逆向思维)
- BZOJ 2956 模积和 (数学推导+数论分块)
- HDU5584 LCM Walk(数学)
- HDU 5584 LCM Walk (数学推导)
- Sumdiv 数论提 (数学很重要),这道题中算法变成了次要因素,数学才是最重要的,注意其中的一个经典公式(求因数和的)(很好推导)
- lightOJ 1278 Sum of Consecutive Integers(数论,数学推导)
- hdu 5584 LCM Walk(数学推导公式,规律)
- 2016 ACM/ICPC Reginal Shengyang hdu 5894 hannnnah_j’s Biological Test (数学推导 Lucas)
- 数学题,不等式推导
- Lucene学习总结之六:Lucene打分公式的数学推导
- BZOJ 4403: 序列统计 (组合数 Lucas 数论推导)
- 求和(数学公式推导、取余运算)
- ACdream 1006 Mengzhu (数学推导)
- Lucene打分公式的数学推导
- 集训日志(二) 数学题(1):数论
- hdu 1046 数学公式推导
- noip2014联合权值 (贪心+数学推导)