/*
translation:
求循环体for(int i = A; i != B; i = (i + C) % 2^k)执行多少次
solution:
扩展欧几里的算法求解线性模方程。
该问题就是求解(A+C*x)%n=B, 其中n为2^k。
变形:(A+C*x)==B(mod n) -> C*x == (B-A)(mod n)
note:
对于方程a*x==b(mod n),令d=gcd(a,n)。该方程有解的充要条件是d|b
然后跑一遍exGcd。通过x=(x(b/d))%n可以求解出方程的一个整数解(不一定是最小解)
然后可以通过x=(x%(n/d)+n/d)%(n/d)即可找出最小解。
date:
2016.10.14
*/
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll A, B, C, k;
void exGcd(ll a, ll b, ll &d, ll &x, ll &y)
{
if(!b) {d = a; x = 1; y = 0;}
else {
exGcd(b, a % b, d, y, x);
y -= x * (a / b);
}
}
int main()
{
while(cin >> A >> B >> C >> k) {
if(A == 0 && B == 0 && C == 0 && k == 0) break;
ll M = (1ll << k);
ll a = C; ll b = (B - A + M) % M; //为了防止产生负数
poj2115(欧几里的算法,线性同余方程)
最新推荐文章于 2021-07-19 17:35:03 发布