posts - 100,  comments - 15,  trackbacks - 0

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==0break;
        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 阅读(323) 评论(0)  编辑 收藏 引用 所属分类: POJ

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理