1 条题解
-
0
题意分析
题目给出一个C语言风格的for循环:
for (variable = A; variable != B; variable += C) statement;
循环开始时将变量初始化为,每次循环后增加,直到等于时停止。所有运算在位无符号整数下进行,即模运算。我们需要计算循环体的执行次数,如果循环不会终止则输出。
解题思路
-
问题转化:循环的执行次数满足以下同余方程:
可以转化为:
这是一个线性同余方程,形式为:
其中,,。
-
线性同余方程求解:线性同余方程有解的条件是能被和的最大公约数整除。即:
如果,则方程无解,循环不会终止,输出。
-
扩展欧几里得算法:用扩展欧几里得算法求解方程,得到特解。然后方程的通解为:
最小正整数解为:
$$x_{\text{min}} = \left( x_0 \cdot \frac{c}{d} \bmod \frac{b}{d} + \frac{b}{d} \right) \bmod \frac{b}{d} $$ -
实现步骤:
- 计算。
- 检查是否能被整除。
- 如果能整除,用扩展欧几里得算法求解并输出最小正整数解;否则输出。
标程
#include <cstdio> #include <iostream> using namespace std; typedef long long ll; ll A, B, C, a, b, c, k, ans; void exgcd(ll a, ll b, ll &x, ll &y, ll &d) { if (!b) { x = 1; y = 0; d = a; } else { exgcd(b, a % b, y, x, d); y -= x * (a / b); } } int main() { while (cin >> A >> B >> C >> k) { if (A == 0 && B == 0 && C == 0 && k == 0) break; a = C; b = 1LL << k; c = B - A; ll x, y, d; exgcd(a, b, x, y, d); if (c % d == 0) { ans = (c / d * x % (b / d) + b / d) % (b / d); cout << ans << endl; } else { puts("FOREVER"); } } return 0; }
-
- 1
信息
- ID
- 1116
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者