題意:轉化成c * x = b - a mod (2 ^ k),解這個模線性方程的最小正整數解即可
Sample Input
3 3 2 16
3 7 2 16
7 3 2 16
3 4 2 16
0 0 0 0
Sample Output
0
2
32766
FOREVER
解方程:ax == b (mod n);【ax % n == b % n】
設線性模方程的一個解為x0
條件①:有d = gcd(a, n)
條件②:有d = ax1 + ny, 由擴展歐幾裡得(Egcd)得到x1的值
條件③:b % d == 0 (有解的條件)
則x0 = x1*(b/d);
證明:
因為:容易求得d = gcd (a, n), 則有d = ax1 + ny①(擴展歐幾裡得定理)
方程①2邊同時模n得:d % n == ax1 % n②
又因為:b % d == 0, 即b是d的倍數;
所以(b/d)必為整數;
所以由②得: b % n == d*(b/d) % n == ax1*(b/d) % n == ax % n
所以很容易可以看出x = x1*(b/d)是方程的一個整數解,得證
參考文獻:
C++代碼
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <set>
//#include <map>
#include <queue>
#include <utility>
#include <iomanip>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <ctype.h>
using namespace std;
#define L long long
L Egcd (L a, L b, L &x, L &y) //擴展歐幾裡得
{
L d, tp;
if (b == 0)
{
x = 1, y = 0;
return a;
}
d = Egcd (b, a%b, x, y);
tp = x;
x = y;
y = tp - (a/b)*y;
return d;
}
void MLE (L a, L b, L n) //解模線性方程
{
L x, y, d;
d = Egcd (a, n, x, y);
if (b % d == 0)
{
L x0 = (b / d * x) % n + n;
cout << x0 % (n/d) << endl;
//對於無數個解形成的一群余數:周期個數是d,周期長度是n/d,也就是最小正整數解在n/d裡,這個聽老師說過,但是忘了為什麼,涉及到群的概念……
}
else puts ("FOREVER"); //無解
}
int main()
{
L a, b, c;
int k;
while (cin >> a >> b >> c >> k)
{
if (!a && !b && !c && !k)
break;
MLE (c, b - a, 1LL << k);
}
return 0;
}