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 }