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

中国剩余定理(CRT)

我好蔡啊
不学这个东东我连任意模数 N T T NTT NTT都学不了

问题

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

{ x ≡ a 1 ( m o d    m 1 ) x ≡ a 2 ( m o d    m 2 ) . . . . . . x ≡ a k ( m o d    m k ) \left\{ \begin{aligned} x≡a_1(\mod m_1)\\ x≡a_2(\mod m_2)\\ ......\\ x≡a_k(\mod m_k) \end{aligned} \right. xa1(modm1)xa2(modm2)......xak(modmk)

其中 m 1 , m 2 , . . . , m k m_1,m_2,...,m_k m1,m2,...,mk两两互质
x x x的最小非负整数解

定理

M = ∏ i = 1 k m i M=\prod_{i=1}^km_i M=i=1kmi,也就是它们的最小公倍数
t i t_i ti M m i t i ≡ 1 ( m o d    m i ) {M\over m_i}t_i≡1(\mod m_i) miMti1(modmi)的最小非负整数解
那么有一个 x x x解为 ∑ i = 1 k a i M m i t i \sum_{i=1}^ka_i{M\over m_i}t_i i=1kaimiMti
通解为 x + k M ( k ∈ Z ) x+kM(k\in \Z) x+kM(kZ),最小非负整数解为 ( x % M + M ) % M (x\% M+M)\%M (x%M+M)%M

证明

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

code

容易发现因为 M m i t i ≡ 1 ( m o d    m i ) {M\over m_i}t_i≡1(\mod m_i) miMti1(modmi)
其实就是求 M m i {M\over m_i} miM关于 m i m_i mi逆元
扩欧实现好了

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)

问题

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

{ x ≡ a 1 ( m o d    m 1 ) x ≡ a 2 ( m o d    m 2 ) . . . . . . x ≡ a k ( m o d    m k ) \left\{ \begin{aligned} x≡a_1(\mod m_1)\\ x≡a_2(\mod m_2)\\ ......\\ x≡a_k(\mod m_k) \end{aligned} \right. xa1(modm1)xa2(modm2)......xak(modmk)

其中 m 1 , m 2 , . . . , m k m_1,m_2,...,m_k m1,m2,...,mk不保证两两互质
x x x的最小非负整数解

求解

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

那么考虑加入第 k k k条方程,即求一个 t ∈ N + t\in\N^+ tN+,使
x + t M ≡ a k ( m o d    m k ) x+tM≡a_k(\mod m_k) x+tMak(modmk),也就是 t M ≡ a k − x ( m o d    m k ) tM≡a_k-x(\mod m_k) tMakx(modmk)
由于 M , a k , x , m k M,a_k,x,m_k M,ak,x,mk都已知,可以看作 a x ≡ c ( m o d    b ) ax≡c(\mod b) axc(modb)
这个也可以用扩欧解

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

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;
}

后记

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

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页