题意:利用了 k位存储系统 的数据特性进行循环。例如int型是16位的,那么int能保存2^16个数据,即最大数为65535(本题默认为无符号),当循环使得i超过65535时,则i会返回0重新开始计数,如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的值。
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <algorithm>
#define N 1010
#define LL long long
using namespace std;
/*
* 已知 a, b, n, 求x 使得ax≡b(mod n)
*
* 令d=gcd(a, n) 先使用扩展欧几里得来求ax+ny=d的解,
* 如果b不能整除d,则无解;否则mod n意义下的解有d个,
* 可以通过对某个解不断的加n/d得到
*
* 时间复杂度 O(log n)
*
*/
long long extend_gcd(long long a, long long b, long long &x, long long &y){
if (b){
long long r = extend_gcd(b, a%b, y, x);
y -= x*(a/b);
return r;
} else {
x = 1;
y = 0;
return a;
}
}
vector <long long> line_mod_equation(long long a, long long b, long long n){
long long x, y;
long long d = extend_gcd(a, n, x, y);
vector<long long> ans;
ans.clear();
if (b%d == 0) {
x %= n;
x += n;
x %= n;
ans.push_back(x*(b/d)%(n/d));
for (long long i = 1; i < d; i++){
ans.push_back((ans[0]+i*n/d)%n);
}
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
long long a, b, c, k, aa, bb, nn, x, y, d;
while(1){
cin >> a >> b >> c >> k;
if (k == 0){
break;
}
aa = c;
bb = b-a;
nn = 1ll<<k;
d = extend_gcd(aa, nn, x, y);
if (bb%d == 0){
x = (x*(bb/d))%nn;
x = ((x%(nn/d)+nn/d))%(nn/d);
printf("%I64d\n",x);
// cout << x << endl //换成cout输出就会WA 为什么啊??
}else{
puts("FOREVER");
}
}
return 0;
}