题解:P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

· · 题解

CRT 模板当然要用 CRT 了。(bushi)

简单介绍 CRT(源自 oiwiki):

定义

中国剩余定理(Chinese Remainder Theorem,CRT)可求解如下形式的一元线性同余方程组(其中 n_1,n_2, \dotsi ,n_k 两两互质):

x \equiv a_1 (mod\ n_1)\\ x \equiv a_2 (mod\ n_2)\\ \quad \vdots\\ x \equiv a_k (mod\ n_k) \end{cases}

过程

(该部分与 oiwiki 上的过程略有不一样,出自我们机房的 XXh神犇)

M=\prod_{i=1}^k n_im_i=\frac{M}{n_i}t_im_i 在模 n_i 意义下的逆元 m_i^{-1}

## 证明 我们需要证明上面算法计算所得的 $x$ 对于任意 $i=1,2,\dotsi,k$ 满足 $x\equiv a_i\ (mod\ n_i)$。 当 $i\not =j$ 时,有 $m_j\equiv0\ (mod\ n_i)$,故 $c_j\equiv m_j\equiv 0\ (mod\ n_i)$。又有 $c_i\equiv m_i\cdot(t_i\ mod\ n_i) \equiv 1\ (mod\ n_i)$,所以有: $$ \begin{aligned} x&\equiv\sum_{j=1}^k a_jc_j&\qquad (mod\ n_i)\\ &\equiv a_ic_i&\qquad (mod\ n_i)\\ &\equiv a_i\cdot m_i\cdot(t_i\ mod\ n_i)&\qquad (mod\ n_i)\\ &\equiv a_i&\qquad (mod\ n_i) \end{aligned} $$ 证毕。 ## 代码实现 ```cpp #include<bits/stdc++.h> #define int long long using namespace std; int qcheng(int a,int b,int mod) { int ans=0; a%=mod; b%=mod; while(b) { if(b&1) ans=(ans+a)%mod; b>>=1; a=(a+a)%mod; } return ans; } int exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1,y=0; return a; } int d=exgcd(b,a%b,x,y); int t=x; x=y,y=t-(a/b)*y; return d; } int k,a[100001],n[100001],x,y,m,M,t[100001],sum; signed main() { cin>>k; m=1; for(int i=1;i<=k;i++) { cin>>a[i]>>n[i]; m*=a[i]; } for(int i=1;i<=k;i++) { M=m/a[i]; int shu=exgcd(M,a[i],x,y);\\求逆元 x=(x%a[i]+a[i])%a[i]; sum=(sum+(qcheng(qcheng(M,x,m),n[i],m)%m+m))%m;\\慢乘防溢出 } cout<<sum; return 0; } ``` 做完后可尝试 [P4777EXCRT](https://www.luogu.com.cn/problem/P4777)。