poj 2115 C Looooops(扩展gcd)
这个题犯了两个小错误,感觉没错,结果怒交了20+遍,各种改看别人题解,感觉思路没有错误,就是wa.
后来看diccuss和自己查错,发现自己的ecgcd里的x*(a/b)写成了x*a/b。还有(LL)1<<k 写成了 (LL)(1<<k),记住了。。。
题意:
对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。
若在有限次内结束,则输出循环次数。
否则输出死循环。取最小的满足 cx mod (2^k) = b - a的正x。
思路:
(A + Cx)%2^k = B;
A + Cx = B + 2^k*y;
Cx - 2^k*y = B - A;
令a = C; b = 2^k; c = B-A;
如果c%d != 0 无解;
否则 q = b/d;
结果为 x*(c/d)%q+q)%q。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #define LL long long 6 using namespace std; 7 8 void exgcd(LL a, LL b, LL &d, LL &x, LL &y) 9 { 10 if(!b) {d = a; x = 1; y = 0; } 11 else {exgcd(b, a%b, d, y, x); y-= x*(a/b); } 12 } 13 int main() 14 { 15 LL a, b, d, x, y, c, q; 16 LL A, B, C, k; 17 while(~scanf("%lld%lld%lld%lld", &A, &B, &C, &k)) 18 { 19 if(A==0&&B==0&&C==0&&k==0) 20 break; 21 a = C; b = (LL)1<<k; //注意1<<k; 22 c = B-A; 23 exgcd(a, b, d, x, y); 24 if(c%d) 25 printf("FOREVER\n"); 26 else 27 { 28 q = b/d; 29 printf("%lld\n", (x*(c/d)%q+q)%q); 30 } 31 } 32 return 0; 33 }