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 }

 

你可能感兴趣的:(oop)