poj2115-Looooops-(扩展欧几里得定理)

Posted shoulinniao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2115-Looooops-(扩展欧几里得定理)相关的知识,希望对你有一定的参考价值。

C Looooops
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions:33752   Accepted: 9832

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
翻译:在循环里,values值为a,每次加c,如果values不等于b,就继续循环下去,死循环输出forever,否则输出循环次数。所有运算都对无符号的k位二进制求模。
解题过程
设p=2^k
起点为a,每次加c,对p求模若能等于b对p求模则有解,否则无解,输出forever
有解的话设解为x
(a+cx)%p = b%p
a%p + cx%p = b%p
cx%p = (b-a)%p
cx%p + 0 = (b-a)%p
cx%p + yp%p = (b-a)%p
形如ax+by=gcd,扩展欧几里得定理。
 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<math.h>
 6 #include<string>
 7 #define ll long long
 8 #define inf 0x3f3f3f3f
 9 using namespace std;
10 // ax + by = gcd(a,b)
11 ll exgcd(ll a, ll b, ll &x, ll &y)//扩展欧几里德定理
12 {
13     if(b==0)//终有一次a%b传进来是0,递归出口
14     {
15         x=1;
16         y=0;
17         return a;
18     }
19     ll q=exgcd(b,a%b,y,x);
20     //最终递归出来,y1=1,x1=0
21     y=y-(a/b)*x;
22     //后面的y相当于下一个递归的x2,x相当于下一个递归的y2,符合推导公式
23     //x1=y2;   y1=x2-[a/b]*y2;
24     return q;
25 }
26 
27 int main()
28 {
29     ll a,b,c,k,p,x,y;
30     while(scanf("%lld %lld %lld %lld",&a,&b,&c,&k)!=EOF&&(a+b+c+k))
31     {
32         p=1;
33         for(ll i=1;i<=k;i++)
34             p=p*2;
35         ll gcd=exgcd(c,p,x,y);
36         ll d=b-a;
37         if(d%gcd)
38             printf("FOREVER
");
39         else
40         {
41             ll  multiple=d/gcd;///倍数
42             p=p/gcd;///通解公式:x=x+b/gcd y=y-a/gcd
43             x=( (x*multiple)%p+p )%p;///求最小正数解
44             printf("%lld
",x);
45         }
46     }
47     return 0;
48 }

 







 

 

























以上是关于poj2115-Looooops-(扩展欧几里得定理)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2115C Looooops[一元线性同余方程]

POJ 2115 C-Looooops | exgcd

POJ2142(扩展欧几里得)

poj2115 C Looooops——扩展欧几里得

POJ 1061 青蛙的约会 扩展欧几里得

poj 1061 青蛙的约会 (扩展欧几里得模板)