来源:http://poj.org/problem?id=2115
题意:就是说一个for循环,变量从a开始,每次增加c,问经过多少次增加能够 (a+c*n) % 2^k = b%2^k,即同余方程。经过变形后可以变成裸的扩展欧几里得
思路:用扩展欧几里得解就可以了。。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
if(b == 0)
return a;
return gcd(b,a%b);
}
ll mi(ll x){
ll f = 1;
for(int i = 1;i <= x; ++i)
f*= 2;
return f;
}
void extend_Eulid(ll a,ll b, ll &x,ll &y){
if(b == 0){
x = 1;
y = 0;
return;
}
else{
extend_Eulid(b,a%b,x,y);
ll temp = x;
x = y;
y = temp - a/b * y;
}
}
int main(){
ll a,b,c,k;
while(scanf("%lld%lld%lld%lld",&a,&b,&c,&k)){
if(a + b + c + k == 0)
break;
ll ans = mi(k);
ll gcdbc = gcd(ans,c);
ll value = (b - a + ans)%ans;
if(value % gcdbc)
printf("FOREVER\n");
else{
c /= gcdbc;
ans /= gcdbc;
value /= gcdbc;
ll xx,yy;
extend_Eulid(ans,c,xx,yy);
xx *= value;
yy *= value;
yy %= ans;
if(yy < 0){
yy = (yy+ans)%ans;
}
printf("%lld\n",yy);
}
}
return 0;
}