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 < 2k) modulo 2k.

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 < 2k) 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


    推论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;
}

posted on 2009-06-12 19:24 极限定律 阅读(2252) 评论(0)  编辑 收藏 引用 所属分类: ACM/ICPC


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(10)

随笔分类

随笔档案

友情链接

搜索

最新评论

阅读排行榜

评论排行榜