一元线性同余方程
定义:
$a$,$b$是整数,$m$是正整数,形如
$axequiv b\,(mod\, m)$
且$x$是未知数的同余式称作一元线性同余方程。
对于方程$axequiv b\,(mod\, m)$, 可以把它写成二元一次不定式$ax+my=b$。要想方程有解,必须满足$(a,m)mid d$。 这时利用扩展欧几里得求出$ax+my=(a,m)$
的一个特解,在乘上$b/(a,m)$就是我们所要的一个特解。
利用公式:
$ax_0+my_0=d=ax+myRightarrow a(x-x_0)+m(y-y_0)=0$
$(frac{a}{(a,m)}, frac{m}{(a,m)}) = 1 $
$x = x_0-frac{m}{(a,m)}t$
这样就得到了$x$的所有解,其中最小的整数解是$ (x\,mod\,frac{m}{(a,m)}+frac{m}{(a,m)} ) \,mod\,frac{m}{(a,m)} $
POJ 2115 就是求当$a=C$,$b=B-A$,$m=2^k$的最小解
#include "iostream" using namespace std; typedef long long LL; void ext_gcd(LL a, LL b, LL &s, LL& x, LL& y) { LL res; if (!b){x = 1; y = 0; s = a;} else { ext_gcd(b, a%b, s, y, x); y -= x*(a/b); } } LL mod_line(LL a, LL b, LL m) { LL x, y, d;ext_gcd(a, m, d, x, y); if (b%d) return -1; LL e = x*(b/d)%(m/d) + (m/d); return e%(m/d); } int main(int argc, char const *argv[]) { LL a,b,c,d; while (cin >> a >> b >> c >> d) { if (!a&&!b&&!c&&!d) break; LL ans = mod_line(c, b-a, (LL)1 << d); if (ans == -1) cout << "FOREVER "; else cout << ans << endl; } return 0; }