poj2115C Looooops

http://poj.org/problem?id=2115

参考人家的 如下

如i=65534,当i+=3时,i=1

其实就是 i=(65534+3)%(2^16)=1

有了这些思想,设对于某组数据要循环x次结束,那么本题就很容易得到方程:

x=[(B-A+2^k)%2^k] /C

即 Cx=(B-A)(mod 2^k)  此方程为 模线性方程,本题就是求X的值。

为了统一

令a=C  

  b=B-A 

  n=2^k

那么原模线性方程变形为:

ax=b (mod n)

该方程有解的充要条件为 gcd(a,n) | b ,即 b% gcd(a,n)==0

令d=gcd(a,n)

有该方程的 最小整数解为 x = e (mod n/d)

其中e = [x0 mod(n/d) + n/d] mod (n/d) ,x0为方程的最小解

那么原题就是要计算b% gcd(a,n)是否为0,若为0则计算最小整数解,否则输出FOREVER

 

据说。。

最小解 X=x*(B/d)%K;之后,为了保证X为最小正整数解需要做如下变换
(X+K)%(K/d)

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<stdlib.h>
 5 #include<cmath>
 6 #define LL long long
 7 using namespace std;
 8 LL exgcd(LL a,LL b,LL &x,LL &y)
 9 {
10     if(b == 0)
11     {
12         x = 1; y = 0; return a;
13     }
14     LL d = exgcd(b, a % b,x,y);
15     LL temp = x;
16     x = y;
17     y = temp - a / b * y;
18     return d;
19 }
20 int main()
21 {
22     LL A,B,C,k;
23     while(cin>>A>>B>>C>>k)
24     {
25         if(!A&&!B&&!C&&!k)
26             break;
27         LL a = C;
28         LL b = B-A;
29         LL n = 1LL<<k;
30         LL x,y;
31         LL d = exgcd(a,n,x,y);
32         if(b%d!=0)
33         {
34             puts("FOREVER");
35             continue;
36         }
37         x = x*(b/d)%n;
38         x = (x+n)%(n/d);
39         cout<<x<<endl;
40     }
41     return 0;
42 }

 

posted @ 2013-02-19 21:15  _雨  阅读(188)  评论(0编辑  收藏  举报