gym 101512 BAPC 2014 I Interesting Integers
来源:互联网 发布:js 滚动加载更多 编辑:程序博客网 时间:2024/06/06 17:39
Problem
codeforces.com/gym/101512/attachments
vjudge.net/contest/186506#problem/I
Meaning
给出一个 正整数 n,要找尽量小的 a 和 b(a < b),使得 n 是以 a 和 b 作为头两项的斐波那契数列的某一项。
Analysis
当 a = b = 1 时,数列增长得最慢,然而即使这样,第 45 项也已经超过
对于斐波那契数列的第 k 项,可以把它写成头两项的线性表达式:fib[k] = c1 * fib[1] + c2 * fib[2]
。而当项数 k 固定下来,系数c1 和 c2 也就是固定的常数了(可以从用矩阵快速幂求斐波那契数列第 k 项的做法理解)。
列出斐波那契数列前几条递推式,不难发现系数 c1 和 c2 规律:c1 = fib[k-2]
,c2 = fib[k-1]
,所以有:fib[k] = fib[k-2] * f[1] + fib[k-1] * fib[2]
。
枚举项数 k,求解c1 * x + c2 * y = n
,相当于找直线上的整点。其中 x 和 y 分别就是所求的 a 和 b 的候选解。
因为要满足 a > 0、b > 0、a < b,而求出的 x 和 y 不一定满足这三个条件,要先做一些偏移,使整点(x,y)移动到直线y = x
上方,然后再更新答案。
Code
#include <iostream>using namespace std;const int N = 1e9, TERM = 45;int fib[TERM+1];void table(){ fib[0] = 0; fib[1] = 1; for(int i = 2; i <= TERM; ++i) fib[i] = fib[i-1] + fib[i-2];}long long extgcd(long long a, long long b, long long &x, long long &y){ long long d = a; if(b) { d = extgcd(b, a % b, y, x); y -= (a / b) * x; } else { x = 1; y = 0; } return d;}int main(){ ios::sync_with_stdio(false); cin.tie(0); table(); int T; cin >> T; while(T--) { int n; cin >> n; int a = 1, b = n - 1; for(int t = TERM; t > 2; --t) { long long x, y, k, // x 的系数、y 的系数 fa = fib[t-2], fb = fib[t-1], // 求解 fa * x + fb * y = gcd(fa, fb) g = extgcd(fa, fb, x, y); // gcd(fa, fb) 不整除 n // 则方程无解 if(n % g) continue; // 方程两边同乘 n / gcd(fa, fb) // 即得 fa * x + fb * y = n 的解 (x,y) x *= n / g; y *= n / g; // 整点移动时的增量 // x 的增量是 fb // y 的增量是 fa fa /= g; fb /= g; // 把整点移到 y = x 上方 // 即 x - k * fb <= y + k * fa if(x > y) { k = (x - y + fa + fb - 1) / (fa + fb); x -= k * fb; y += k * fa; } // 保证整点在 y = x 上方的前提下 // 尽量地往下移,以得到最小的 y // y - k * fa >= x + k * fb k = (y - x) / (fa + fb); x += k * fb; y -= k * fa; // 更新答案 if(x > 0 && y > 0) { if(b > y) a = x, b = y; else if(b == y && a > x) a = x, b = y; } } cout << a << ' ' << b << '\n'; } return 0;}
Post Script
fib[1] = a
fib[2] = b
fib[3] = a + b
fib[4] = fib[2] + fib[3] = a + 2b
fib[5] = fib[3] + fib[4] = 2a + 3b
fib[6] = fib[4] + fib[5] = 3a + 5b
fib[7] = fib[5] + fib[6] = 5a + 8b
……
fib[n] = fib[n-2] * a + fib[n-1] * b
- gym 101512 BAPC 2014 I Interesting Integers
- gym 101512 BAPC 2014 I Interesting Integers (拓展欧几里得 + 斐波那契)
- gym 101512 BAPC 2014 B Button Bashing
- 【扩展欧几里得】BAPC2014 I Interesting Integers (Codeforces GYM 100526)
- Interesting Integers(CF---BAPC 14 + hnoj11589)扩展欧几里得
- BAPC2014 I&&HUNNU11589:Interesting Integers
- 斐波那契首项 BAPC2014 I&&HUNNU11589:Interesting Integers
- sicily 14550 Interesting Integers
- Gym 100507J Scarily interesting!
- GYM100526 Interesting Integers(扩展欧几里得)
- HUNAN Interesting Integers(爆力枚举)
- 2014 Benelux Algorithm Programming Contest (BAPC 14)
- BAPC 2014(Highway Hassle-加油站问题)
- 计算几何 BAPC 14 C itadel Construction (Gym 100526C )
- CodeForces Gym 100735I
- Mirrored String I Gym
- Gym 101147.I
- Gym 101164.I
- Hibernate入门
- iframe宽度高度的自适应的问题
- mysql 库的操作
- 奶牛博览会——双背包问题
- 原生js实现图片在固定窗口内放缩、拖拽
- gym 101512 BAPC 2014 I Interesting Integers
- [LeetCode] Algorithms-3.Longest Substring Without Repeating Characters
- mysql表相关的约束,主键外键。
- POJ 2388.Who's in the Middle
- 往eclipse项目中添加jar包
- asp.net core2.0 JWT Bearer 注意添加认证服务
- Linux ubtun 安装wireshark
- 打印X图
- Hive