版权声明:如需转载,记得标识出处 https://blog.csdn.net/godleaf/article/details/83065308
题目链接:http://poj.org/problem?id=2115
需要注意的有几点:
第一: exgcd (a, b, x, y) ; 起初以为 y 的最小正整数解是 y = (y % a + a) % a;但事实上最小正整数解是 int tmp = a / gcd (a, b);
y = (y % tmp + tmp) % tmp;
第二: 如果题目要求的是x,表达式最好这样设 ax - by = c ; 如果要求的是 y ,表达式最好这样设 by - ax = c;这样可以避免一些正负号的麻烦;
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
void exgcd (ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1; y = 0; return;
} else {
exgcd (b, a % b, y, x); y -= x*(a/b);
}
}
ll gcd (ll a, ll b) {
return !b ? a : gcd (b, a % b);
}
// (A + a*C) % 2^k == B
// A + a*C - B = b*2^k
// y*C - x*2^k = (B-A)
int main (void)
{
ll A, B, C, k;
while (scanf ("%lld%lld%lld%lld", &A, &B, &C, &k) != EOF) {
if (!A && !B && !C && !k) break;
ll c = B-A, g = gcd (1ll<<k, C);
if (c % g) printf ("FOREVER\n");
else {
ll x, y;
exgcd (1ll<<k, C, x, y);
y *= (c/g);
y = (y%((1ll<<k)/g) + (1ll<<k)/g) % ((1ll<<k)/g);
printf ("%lld\n", y);
}
}
return 0;
}