POJ 2115C Looooops[一元线性同余方程]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2115C Looooops[一元线性同余方程]相关的知识,希望对你有一定的参考价值。
一元线性同余方程
定义:
$a$,$b$是整数,$m$是正整数,形如
$ax\equiv b\,(mod\, m)$
且$x$是未知数的同余式称作一元线性同余方程。
对于方程$ax\equiv b\,(mod\, m)$, 可以把它写成二元一次不定式$ax+my=b$。要想方程有解,必须满足$(a,m)\mid d$。 这时利用扩展欧几里得求出$ax+my=(a,m)$
的一个特解,在乘上$b/(a,m)$就是我们所要的一个特解。
利用公式:
$ax_0+my_0=d=ax+my\Rightarrow 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\n"; else cout << ans << endl; } return 0; }
以上是关于POJ 2115C Looooops[一元线性同余方程]的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2115 C Looooops (扩展欧几里德 + 线性同余方程)
POJ - 2115C Looooops 扩展欧几里得(做的少了无法一眼看出)
POJ 1061 - 青蛙的约会 - [exgcd求解一元线性同余方程]