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 }

 

posted @ 2014-06-07 17:28  水门  阅读(149)  评论(0编辑  收藏  举报