预习心得 - CRT/exCRT
一个求线性同余方程组的算法,如下:
\[\begin{cases}
x\equiv a_1(\bmod m_1) \\
x\equiv a_2(\bmod m_2) \\
x\equiv a_3(\bmod m_3) \\
\dots
\end{cases}
\]
CRT 定理在互质条件下的解法
当 \(m_i\) 两两互质,方程一定有解。并且在 \(0\sim(\prod m_i)-1\) 内有唯一解。可以理解为找到一个数 \(x\),我们可以构造出一个解,然后每一次增加 \((\prod m_i)-1\) 为一个循环,但不一定是最小的解。读者自证不难,这里给出构造方法如下:
我们先考虑构造 \(m\) 组方程,其中第 \(i\) 组存在一个 \(m_i=1\),其余 \(m_i=0\)。我们可以解出一些最小解,设为 \(x_i\)。然后我们设 \(M=\prod m_i\),答案就是 \(\sum x_im_i \bmod M\)。我们有余数的可乘性与可加性,把这些方程的解加起来,相当于构造了一些拆开每一个 \(m_i\) 的方程,解出来,加回去就是原方程。
在不互质条件下的解法
我们可以考虑通过原有方程推出一个其他的同余方程,不停消除方程,就会出现最后的线性同余方程。代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return a;
}
ll d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
void crt(ll &a,ll &b,ll c,ll d){
if(a==-1&&b==-1)
return;
ll x,y;
ll g=exgcd(b,d,x,y);
if((c-a)%g!=0){ // No Solution.
a=-1,b=-1;
return;
}
d/=g;
ll t0=((c-a)/g%d*x%d+d)%d;
a=b*t0+a,b=b*d;
}
int n;
ll a,b,c,d;
void solve(){
cin>>n;
a=0,b=1;
for(int i=1;i<=n;i++){
cin>>d>>c;
crt(a,b,c,d);
}
cout<<a<<"\n";
}
signed main(){
solve();
return 0;
}
文章同步载入于洛谷,详见文章下方链接。
本文来自博客园,作者:Ivan422,转载请注明原文链接:https://www.cnblogs.com/Exfish/p/23270037。

浙公网安备 33010602011771号