poj 2115 扩展欧几里得
题目链接:http://poj.org/problem?id=2115
题意:
给出一段循环程序,循环体变量初始值为 a,结束不等于 b ,步长为 c,看要循环多少次,其中运算限制在 k位;死循环输出FOREVER
那么这里就是:
(b-a)%gcd(c,n)==0,有解;否则无解。
有解的时候,有多少解呢?
求出来的解是:
这里就是: x * (b-a) / gcd(c,n)
其中最小的解又是多少呢?
定理:
令 t = n / d;
最小的解是:(x%t+t)%t;
1 #include <cstdio> 2 #include <cmath> 3 4 using namespace std; 5 6 long long x,y; 7 //d = gcd(a,b) = ax + by 8 long long Extended_Euclid(long long a,long long b) { 9 10 if(b==0) { 11 x = 1; 12 y = 0; 13 return a; 14 } 15 long long d = Extended_Euclid(b,a%b); 16 long long tmp = x; 17 x = y; 18 y = tmp - a/b*y; 19 return d; 20 } 21 22 23 24 int main() 25 { 26 long long a,b,c,k; 27 while(scanf("%lld%lld%lld%lld",&a,&b,&c,&k)) { 28 if(a==0&&b==0&&c==0&&k==0) 29 break; 30 long long n = (long long)1<<k; 31 long long d = Extended_Euclid(c,n); 32 if((b-a)%d) { 33 puts("FOREVER"); 34 } 35 else { 36 long long t = n/d; 37 x = (x*(b-a)/d%t+t)%t; 38 printf("%lld\n",x); 39 } 40 } 41 42 return 0; 43 }