中国剩余定理与扩展中国剩余定理

中国剩余定理(CRT)

我好蔡啊
不学这个东东我连任意模数\(NTT\)都学不了

问题

中国剩余定理用于求解同余方程组

\[ \left\{ \begin{aligned} x≡a_1(\mod m_1)\\ x≡a_2(\mod m_2)\\ ......\\ x≡a_k(\mod m_k) \end{aligned} \right. \]

其中\(m_1,m_2,...,m_k\)两两互质
\(x\)的最小非负整数解

定理

\(M=\prod_{i=1}^km_i\),也就是它们的最小公倍数
\(t_i\)\({M\over m_i}t_i≡1(\mod m_i)\)的最小非负整数解
那么有一个\(x\)解为\(\sum_{i=1}^ka_i{M\over m_i}t_i\)
通解为\(x+kM(k\in \Z)\),最小非负整数解为\((x\% M+M)\%M\)

证明

对于\(M\over m_i\),它一定是其他\(m\)的倍数且不整除\(m_i\)(注意限制)
那么\(∀k≠i,a_i{M\over m_i}t_i≡0(\mod m_k)\),这个是因为\({M\over m_i}\mod m_k=0\)
由于\({M\over m_i}t_i≡1(\mod m_i)\),所以\(a_i{M\over m_i}t_i≡a_i(\mod m_i)\)
又因为\(x=\sum_{i=1}^ka_i{M\over m_i}t_i\),代入方程组,方程组成立

code

容易发现因为\({M\over m_i}t_i≡1(\mod m_i)\)
其实就是求\({M\over m_i}\)关于\(m_i\)逆元
扩欧实现好了

inline ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if (b==0){x=1,y=0;return a;}
	ll ans=exgcd(b,a%b,y,x);
	y-=x*(a/b);return ans;
}
inline ll CRT(ll a[],ll m[],ll n)
{
	ll M=1ll,x,y,ans=0ll;
	fo(i,1,n)M*=m[i];
	fo(i,1,n)
	{
		ll tmp=M/m[i];exgcd(tmp,m[i],x,y);
		ans=(ans+a[i]*x*tmp)%M;
	}
	return (ans+M)%M;
}

扩展中国剩余定理(EXCRT)

问题

扩展中国剩余定理用于求解同余方程组

\[ \left\{ \begin{aligned} x≡a_1(\mod m_1)\\ x≡a_2(\mod m_2)\\ ......\\ x≡a_k(\mod m_k) \end{aligned} \right. \]

其中\(m_1,m_2,...,m_k\)不保证两两互质
\(x\)的最小非负整数解

求解

设前\(k-1\)条方程组成的方程组的一个解为\(x\)
\(M=\prod_{i=1}^{k-1}m_i\),那么通解就为\(x+kM(k\in\Z)\)

那么考虑加入第\(k\)条方程,即求一个\(t\in\N^+\),使
\(x+tM≡a_k(\mod m_k)\),也就是\(tM≡a_k-x(\mod m_k)\)
由于\(M,a_k,x,m_k\)都已知,可以看作\(ax≡c(\mod b)\)
这个也可以用扩欧解

扩欧可以直接解出\(ax+by=gcd(a,b)\)的解\(x_0,y_0\)
于是如果直接解\(ax+by=c\)\(x_0\)还要除掉\({\gcd(a,b)\over c}\)就是\(x_0c\over \gcd(a,b)\)
原方程相当于\(ax\mod b=c\),转化为\(ax+by=c\),用上面的方法解就好了
注意如果不满足\(gcd(a,b)|c\),这条方程无解,整个方程组也无解
好像就是这样了,一共要做\(n-1\)次扩欧,注意各种取模细节

code

inline ll mul(ll x,ll y,ll mod)
{
	return (x*y-(ll)((long double)x/mod*y)*mod+mod)%mod;     
}
inline ll EXCRT(ll a[],ll m[],ll n)
{
	ll M=m[1],x,y,ans=a[1];
	fo(i,2,n)
	{
		ll gcd=exgcd(M,m[i],x,y),tmp=(a[i]-ans%m[i]+m[i])%m[i];
		if (tmp%gcd!=0)return -1;
		x=mul(x,tmp/gcd,m[i]/gcd);
		ans+=x*M,M*=m[i]/gcd,ans=(ans%M+M)%M;
	}
	return (ans%M+M)%M;
}

后记

感觉这种数学的东西还得多学多记多背……
本人版权意识薄弱……

posted @ 2019-08-06 10:23  路人黑的纸巾  阅读(231)  评论(0编辑  收藏  举报