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

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

Description

A Compiler Mystery: We are given a C-language style for loop of type
for (variable = A; variable != B; variable += C)

statement;

I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repeats statement followed by increasing the variable by C. We want to know how many times does the statement get executed for particular values of A, B and C, assuming that all arithmetics is calculated in a k-bit unsigned integer type (with values 0 <= x < 2 k) modulo 2 k.

Input

The input consists of several instances. Each instance is described by a single line with four integers A, B, C, k separated by a single space. The integer k (1 <= k <= 32) is the number of bits of the control variable of the loop and A, B, C (0 <= A, B, C < 2 k) are the parameters of the loop.

The input is finished by a line containing four zeros.

Output

The output consists of several lines corresponding to the instances on the input. The i-th line contains either the number of executions of the statement in the i-th instance (a single integer number) or the word FOREVER if the loop does not terminate.

Sample Input

3 3 2 16
3 7 2 16
7 3 2 16
3 4 2 16
0 0 0 0

Sample Output

0
2
32766
FOREVER

Source

CTU Open 2004

    推论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  < iostream >
using   namespace  std;

long   long  ext_gcd( long   long  a, long   long  b, long   long   & x, long   long   & y) {
    
long long t,ret;
    
if(!b){
        x
=1,y=0;
        
return a;
    }

    ret
=ext_gcd(b,a%b,x,y);
    t
=x,x=y,y=t-a/b*y;
    
return ret;
}

long   long  modular_linear( long   long  a, long   long  b, long   long  n) {
    
long long 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() {
    
long long 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,1LL<<k);
        
if(d==-1)
            puts(
"FOREVER");
        
else
            printf(
"%lld\n",d);
    }

    
return 0;
}

你可能感兴趣的:(POJ 2115 模线性方程 ax=b(mod n))