A+C*X=B(%2^K)
C*X=B-A(%2^K)
令a=c,b=B-A,n=2^K;
利用以下结论(具体证明见《算法导论):
推论1:方程ax=b(mod n)对于未知量x有解,当且仅当gcd(a,n) | b。
推论2:方程ax=b(mod n)或者对模n有d个不同的解,其中d=gcd(a,n),或者无解。
定理1:设d=gcd(a,n),假定对整数x和y满足d=ax+by(比如用扩展Euclid算法求出的一组解)。如果d | b,则方程ax=b(mod n)有一个解x0满足x0=x*(b/d) mod n 。特别的设e=x0+n,方程ax=b(mod n)的最小整数解x1=e mod (n/d),最大整数解x2=x1+(d-1)*(n/d)。
定理2:假设方程ax=b(mod n)有解,且x0是方程的任意一个解,则该方程对模n恰有d个不同的解(d=gcd(a,n)),分别为:xi=x0+i*(n/d) mod n 。
a*x=b(%n) => a*x+n*y=b
d=ext_gcd(a,n,x0,y0)
最小整数解x1=(x0*(b/d)%n+n)%(n/d);
#include <iostream>
using namespace std;
__int64 exgcd(__int64 a, __int64 b, __int64 &x, __int64 &y)
{
if(b==0)
{
x=1;y=0;return a;
}
__int64 r=exgcd(b, a%b, x, y);
__int64 t=x;x=y;y=t-a/b*y;
return r;
}
int main()
{
__int64 A,B,C,K;
__int64 a,b,n,d,x,y,e;
while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&K)!=EOF)
{
if(A==0 && B==0 && C==0 && K==0) break;
a=C;
n=((__int64)1<<K); //小心溢出
b=B-A;
d=exgcd(a, n, x, y);
if(b%d) {printf("FOREVER\n"); continue;}
e=x*(b/d)%n+n;
printf("%I64d\n",e%(n/d));
}
return 0;
};
posted on 2010-03-31 22:48
wyiu 阅读(379)
评论(0) 编辑 收藏 引用 所属分类:
POJ