Problem Description
题目理解参考了博客:優YoU http://blog.csdn.net/lyy289065406/article/details/6648546 其实就是让你求Cx=(B-A)(mod 2^k)方程的x值
思路
我们先讨论ax ≡ b(mod)n 意思就是a和b关于模n同余。so:ax - b = ny, 转换一下 ax - ny = b。ax - ny = gcd(a, n)这个是扩展欧几里德
扩展欧几里德 :ax + by = gcd(a, b) 我们可以求出一组解(x0, y0)。我们令gcd(a, b) = g其他的解(x0 - k*b/g , y0 + k*a/g ), 如果是ax + by = c;如果c是g的倍数 的一组解( x0*c/g, y0*c/g), 否则c不是g的倍数无解
所以ax - ny = b的问题就可以解决了a = C, n = 2^k, b = (B - A) 。
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
LL extend_gcd(LL a, LL b, LL &x, LL &y)//扩展欧几里德
{
if(b == 0)//b=0的时候,ax + by = gcd(a, b)。gcd(a,b)=ax,所以x=1, y=0.
{
x = 1; y = 0;
return a;
}
else
{
LL r = extend_gcd(b, a%b, y, x);
y -= x*(a/b);//x=y`,y=x`-a/b*y`
return r;
}
}
int main()
{
LL A, B, C, k;
LL a, b, n, d;
while(~scanf("%lld %lld %lld %lld", &A, &B, &C, &k))
{
if(!A && !B && !C && !k) break;
a = C;
n = (LL)1<<k;
b = (B - A + n) % n;
long long x, y;
d = extend_gcd(a, n, x, y);//扩展欧几里德d为最大公约数,(x, y)为一组解
//printf("%lld %lld %lld %lld %lld %lld\n", a, b, n, d, x, y);
if(b%d == 0)//有一组解
{
x%=n; x+=n; x%=n;
printf("%lld\n", (x*(b/d)%(n/d)));//输出了其中最小的解
}
else printf("FOREVER\n");
}
}