POJ 2115 模线性方程 ax=b(mod n)

/*

(x*c+a)%(2^k)==b →(x*c)%(2^k)==b-a  

满足定理:

推论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 。

*/

#include<stdio.h>

__int64 ext_gcd(__int64  a,__int64 b,__int64 &x,__int64 &y)

{

    if(b==0){

        x=1;y=0; return a;

    }



        __int64 d=ext_gcd(b,a%b,x,y);

        __int64 t = x;

        x = y;

        y = t - a / b * y;

        return d;

}

__int64 modular_linear(__int64 a,__int64 b,__int64 n){

    __int64 d,e,x,y;

    d=ext_gcd(a,n,x,y);

    if(b%d)

        return -1;

    e=x*(b/d)%n+n;

    return e%(n/d);

}

int main(void)

{

     __int64 d,a,b,c,k;

    while(scanf("%lld %lld %lld %lld",&a,&b,&c,&k),a||b||c||k){

        d=modular_linear(c,b-a,(__int64)1<<k);

        if(d==-1)

            puts("FOREVER");

        else

            printf("%lld\n",d);

    }

    return 0;

}

你可能感兴趣的:(poj)