POJ 2115C Looooops[一元线性同余方程]

一元线性同余方程

定义:

$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;
}
View Code



 

原文地址:https://www.cnblogs.com/cniwoq/p/7260412.html