# 中国剩余定理

## 问题

$\left\{\begin{array}{c}x\equiv {c}_{1}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{1}\right)\\ x\equiv {c}_{2}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{2}\right)\\ x\equiv {c}_{3}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{3}\right)\\ ...\\ x\equiv {c}_{k}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{k}\right)\end{array}$

x的最小正（非负）整数解

## 结论

$M={m}_{1}\ast {m}_{2}\ast {m}_{3}\ast ...\ast {m}_{k}$$M=m_1*m_2*m_3*...*m_k$
$x=\left(\sum _{i=1}^{k}{c}_{i}\ast \frac{M}{{m}_{i}}\ast inv\left(\frac{M}{{m}_{i}},mi\right)\right)\mathrm{%}M$$x=(\sum\limits_{i=1}^k c_i*{M\over m_i}*inv({M\over m_i},mi))\%M$

## 证明

a.在模M意义下x只有唯一解 （有多解那还了得）
b.令${n}_{i}$$n_i$满足${n}_{i}\mathrm{%}\frac{M}{{m}_{i}}=0$$n_i\% {M\over m_i}=0$${n}_{i}\mathrm{%}{m}_{i}=1$$n_i\% m_i=1$，则$N=\sum _{i=1}^{k}{c}_{i}\ast {n}_{i}$$N=\sum\limits_{i=1}^k c_i*n_i$为原问题的一个解
c.根据上面的式子容易得出${n}_{i}=\frac{M}{{m}_{i}}x,{n}_{i}={m}_{i}y+1$$n_i={M\over m_i}x,n_i=m_iy+1$，则$\frac{M}{{m}_{i}}x={m}_{i}y+1$${M\over m_i}x=m_iy+1$，即$\frac{M}{{m}_{i}}x-{m}_{i}y=1$${M\over m_i}x-m_iy=1$
d.由于${m}_{i}$$m_i$两两互质，所以$\frac{M}{{m}_{i}}$${M\over m_i}$${m}_{i}$$m_i$也互质，令$a=\frac{M}{{m}_{i}},b={m}_{i}$$a={M\over m_i},b=m_i$，则$ax-by=1$$ax-by=1$
e.可以发现我们已经将其化简成扩展欧几里得的基本形式$ax+by=\left(a,b\right)$$ax+by=(a,b)$，其中也可以认为x为a在模b意义下的逆元

## 代码

codevs 3990

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long

LL k,l,r,n,M,x,y,Min,ans,m[15],c[15];

void exgcd(LL a,LL b,LL &x,LL &y)
{
if (!b) x=1,y=0;
else exgcd(b,a%b,y,x),y-=a/b*x;
}
int main()
{
scanf("%d%lld%lld",&k,&l,&r);
M=1LL;
for (int i=1;i<=k;++i)
{
scanf("%lld%lld",&m[i],&c[i]);
M*=m[i];
}
for (int i=1;i<=k;++i)
{
LL a=M/m[i],b=m[i];
exgcd(a,b,x,y);
x=(x%b+b)%b;
if (!x) x+=b;
n+=c[i]*a*x;
}
n%=M;
if (!n) n+=M;

if (r>=n)
ans=(r-n)/M+1;
if (l>=n) ans=ans-((l-n)/M+1);
if ((l-n)%M==0) ++ans;
if (ans)
{
if (l<=n) Min=n;
else Min=n+((l-n)/M+1)*M;
}
printf("%lld\n%lld\n",ans,Min);
}

# 扩展中国剩余定理

## 问题

$\left\{\begin{array}{c}x\equiv {c}_{1}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{1}\right)\\ x\equiv {c}_{2}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{2}\right)\\ x\equiv {c}_{3}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{3}\right)\\ ...\\ x\equiv {c}_{k}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{k}\right)\end{array}$

x的最小正（非负）整数解

## 结论

$x\equiv {c}_{1}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{1}\right)$$x\equiv c_1\pmod {m_1}$
$x\equiv {c}_{2}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{m}_{2}\right)$$x\equiv c_2\pmod {m_2}$

$m=\frac{{m}_{1}{m}_{2}}{\left({m}_{1},{m}_{2}\right)}$$m={m_1m_2\over (m_1,m_2)}$
$c=\left(inv\left(\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)},\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)\ast \frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}\right)\mathrm{%}\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\ast {m}_{1}+{c}_{1}$$c=(inv({m_1\over (m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)})\%{m_2\over (m_1,m_2)}*m_1+c_1$

$x=c\mathrm{%}m$$x=c\%m$即为原问题的一个解

## 证明

a.将两个方程写成$x={m}_{1}{k}_{1}+{c}_{1},x={m}_{2}{k}_{2}+{c}_{2}$$x=m_1k_1+c_1,x=m_2k_2+c_2$，两式联立得${m}_{1}{k}_{1}+{c}_{1}={m}_{2}{k}_{2}+{c}_{2}$$m_1k_1+c_1=m_2k_2+c_2$，移项${m}_{1}{k}_{1}={c}_{2}-{c}_{1}+{m}_{2}{k}_{2}$$m_1k_1=c_2-c_1+m_2k_2$
b.根据贝祖定理，以上等式有解充要条件为$\left({m}_{1},{m}_{2}\right)|\left({c}_{2}-{c}_{1}\right)$$(m_1,m_2)|(c_2-c_1)$
c.将等式两边同除$\left({m}_{1},{m}_{2}\right)$$(m_1,m_2)$$\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)}\ast {k}_{1}=\frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}+\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\ast {k}_{2}$${m_1\over(m_1,m_2)}*k_1={(c_2-c_1)\over (m_1,m_2)}+{m_2\over (m_1,m_2)}*k_2$，即$\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)}{k}_{1}\equiv \frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)$${m_1\over(m_1,m_2)}k_1\equiv {(c_2-c_1)\over (m_1,m_2)}\pmod {{m_2\over(m_1,m_2)}}$，进一步化简${k}_{1}\equiv inv\left(\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)},\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)\ast \frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)$$k_1\equiv inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}\pmod {{m_2\over(m_1,m_2)}}$${k}_{1}=inv\left(\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)},\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)\ast \frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}+y\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}$$k_1=inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}+y{{m_2\over (m_1,m_2)}}$
d.将其回代$x={m}_{1}{k}_{1}+{c}_{1}$$x=m_1k_1+c_1$，得$x=inv\left(\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)},\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)\ast \frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}\ast {m}_{1}+y\frac{{m}_{1}{m}_{2}}{\left({m}_{1},{m}_{2}\right)}+{c}_{1}$$x=inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}*m_1+y{{m_1m_2\over (m_1,m_2)}}+c_1$，即$x\equiv inv\left(\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)},\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)\ast \frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}\ast {m}_{1}+{c}_{1}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}\frac{{m}_{1}{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)$$x\equiv inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}*m_1+c_1\pmod {{m_1m_2\over (m_1,m_2)}}$
e.至此我们又将其化简成了$x\equiv c\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}m\right)$$x\equiv c\pmod m$的形式，其中$m=\frac{{m}_{1}{m}_{2}}{\left({m}_{1},{m}_{2}\right)}$$m={m_1m_2\over (m_1,m_2)}$$c=\left(inv\left(\frac{{m}_{1}}{\left({m}_{1},{m}_{2}\right)},\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\right)\ast \frac{\left({c}_{2}-{c}_{1}\right)}{\left({m}_{1},{m}_{2}\right)}\right)\mathrm{%}\frac{{m}_{2}}{\left({m}_{1},{m}_{2}\right)}\ast {m}_{1}+{c}_{1}$$c=(inv({m_1\over (m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)})\%{m_2\over (m_1,m_2)}*m_1+c_1$

## 代码

pku 2891

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
#define N 1005

int k;
LL c[N],m[N],c1,c2,m1,m2,t;
bool flag;

LL gcd(LL a,LL b)
{
if (!b) return a;
else return gcd(b,a%b);
}
void exgcd(LL a,LL b,LL &x,LL &y)
{
if (!b) x=1LL,y=0LL;
else exgcd(b,a%b,y,x),y-=a/b*x;
}
LL inv(LL a,LL b)
{
LL x=0LL,y=0LL;
exgcd(a,b,x,y);
x=(x%b+b)%b;
if (!x) x+=b;
return x;
}
int main()
{
while (~scanf("%d",&k))
{
flag=true;
for (int i=1;i<=k;++i)
scanf("%I64d%I64d",&m[i],&c[i]);
for (int i=2;i<=k;++i)
{
m1=m[i-1],m2=m[i],c1=c[i-1],c2=c[i];
t=gcd(m1,m2);
if ((c2-c1)%t!=0) {flag=false;break;}
m[i]=m1*m2/t;
c[i]=inv(m1/t,m2/t)*((c2-c1)/t)%(m2/t)*m1+c1;
c[i]=(c[i]%m[i]+m[i])%m[i];
}
if (!flag) puts("-1");
else printf("%I64d\n",c[k]);
}
}

# Lucas定理

## 问题

${C}_{n}^{m}\mathrm{%}p$$C_n^m\%p$，其中p为质数

## 结论

$n={n}_{k}\ast {p}^{k}+{n}_{k-1}\ast {p}^{k-1}+...+{n}_{2}\ast {p}^{2}+{n}_{1}\ast p+{n}_{0}$$n=n_k*p^k+n_{k-1}*p^{k-1}+...+n_2*p^2+n_1*p+n_0$
$m={m}_{k}\ast {p}^{k}+{m}_{k-1}\ast {p}^{k-1}+...+{m}_{2}\ast {p}^{2}+{m}_{1}\ast p+{m}_{0}$$m=m_k*p^k+m_{k-1}*p^{k-1}+...+m_2*p^2+m_1*p+m_0$
${C}_{n}^{m}=\prod _{i=0}^{k}{C}_{{n}_{i}}^{{m}_{i}}$$C_n^m=\prod\limits_{i=0}^k C_{n_i}^{m_i}$

## 代码

zoj 3557

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long

LL n,m,Mod;

LL fast_pow(LL a,LL p)
{
LL ans=1LL;
for (;p;p>>=1,a=a*a%Mod)
if (p&1)
ans=ans*a%Mod;
return ans;
}
LL inv(LL x)
{
return fast_pow(x,Mod-2);
}
LL C(LL n,LL m)
{
if (m>n) return 0LL;
LL up=1LL,down=1LL;
for (LL i=n-m+1;i<=n;++i) up=up*i%Mod;
for (LL i=1;i<=m;++i) down=down*i%Mod;
return up*inv(down)%Mod;
}
LL lucas(LL n,LL m)
{
if (m>n) return 0LL;
LL ans=1;
for (;m;n/=Mod,m/=Mod)
ans=ans*C(n%Mod,m%Mod)%Mod;
return ans;
}
int main()
{
while (~scanf("%lld%lld%lld",&n,&m,&Mod))
printf("%lld\n",lucas(n-m+1,m));
}

# 扩展Lucas定理

## 问题

${C}_{n}^{m}\mathrm{%}p$$C_n^m\%p$

## 结论

$p={{p}_{1}}^{{k}_{1}}\ast {{p}_{2}}^{{k}_{2}}\ast ...\ast {{p}_{q}}^{{k}_{q}}$$p={p_1}^{k_1}*{p_2}^{k_2}*...*{p_q}^{k_q}$

$\left\{\begin{array}{c}ans\equiv {c}_{1}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{{p}_{1}}^{{k}_{1}}\right)\\ ans\equiv {c}_{2}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{{p}_{2}}^{{k}_{2}}\right)\\ ...\\ ans\equiv {c}_{q}\phantom{\rule{0.444em}{0ex}}\left(\mathrm{mod}\phantom{\rule{0.333em}{0ex}}{{p}_{q}}^{{k}_{q}}\right)\end{array}$

## 证明

a.由于同于方程组在模$p={{p}_{1}}^{{k}_{1}}\ast {{p}_{2}}^{{k}_{2}}\ast ...\ast {{p}_{q}}^{{k}_{q}}$$p={p_1}^{k_1}*{p_2}^{k_2}*...*{p_q}^{k_q}$意义下有唯一解，可以证明上面做法的正确性
b.由于$p={{p}_{1}}^{{k}_{1}}\ast {{p}_{2}}^{{k}_{2}}\ast ...\ast {{p}_{q}}^{{k}_{q}}$$p={p_1}^{k_1}*{p_2}^{k_2}*...*{p_q}^{k_q}$实质上是将p进行质因数分解，所以${{p}_{i}}^{{k}_{i}}$${p_i}^{k_i}$满足两两互质，可以直接用中国剩余定理合并
c.对于如何求${C}_{n}^{m}\mathrm{%}{{p}_{i}}^{{k}_{i}}$$C_n^m\%{p_i}^{k_i}$

d.对于如何求$n!\mathrm{%}{{p}_{i}}^{{k}_{i}}$$n!\%{p_i}^{k_i}$

$n!=1\ast 2\ast 3\ast 4\ast 5\ast 6\ast 7\ast 8\ast 9\ast 10\ast 11\ast 12\ast 13\ast 14\ast 15\ast 16\ast 17\ast 18\ast 19$$n!=1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19$
$=\left(1\ast 2\ast 4\ast 5\ast 7\ast 8\ast 10\ast 11\ast 13\ast 14\ast 16\ast 17\ast 19\right)\ast {3}^{6}\ast \left(1\ast 2\ast 3\ast 4\ast 5\ast 6\right)$$=(1*2*4*5*7*8*10*11*13*14*16*17*19)*3^6*(1*2*3*4*5*6)$

e.最后一个问题是对于求出的$m!\mathrm{%}{{p}_{i}}^{{k}_{i}}$$m!\%{p_i}^{k_i}$$\left(n-m\right)!\mathrm{%}{{p}_{i}}^{{k}_{i}}$$(n-m)!\%{p_i}^{k_i}$有可能与${{p}_{i}}^{{k}_{i}}$${p_i}^{k_i}$不互质，无法求逆元

## 代码

codeforces2015ICL,Finals,Div.1#J

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long

LL n,m,MOD,ans;

LL fast_pow(LL a,LL p,LL Mod)
{
LL ans=1LL;
for (;p;p>>=1,a=a*a%Mod)
if (p&1)
ans=ans*a%Mod;
return ans;
}
void exgcd(LL a,LL b,LL &x,LL &y)
{
if (!b) x=1LL,y=0LL;
else exgcd(b,a%b,y,x),y-=a/b*x;
}
LL inv(LL A,LL Mod)
{
if (!A) return 0LL;
LL a=A,b=Mod,x=0LL,y=0LL;
exgcd(a,b,x,y);
x=((x%b)+b)%b;
if (!x) x+=b;
return x;
}
LL Mul(LL n,LL pi,LL pk)
{
if (!n) return 1LL;
LL ans=1LL;
if (n/pk)
{
for (LL i=2;i<=pk;++i)
if (i%pi) ans=ans*i%pk;
ans=fast_pow(ans,n/pk,pk);
}
for (LL i=2;i<=n%pk;++i)
if (i%pi) ans=ans*i%pk;
return ans*Mul(n/pi,pi,pk)%pk;
}
LL C(LL n,LL m,LL Mod,LL pi,LL pk)
{
if (m>n) return 0LL;
LL a=Mul(n,pi,pk),b=Mul(m,pi,pk),c=Mul(n-m,pi,pk);
LL k=0LL,ans;
for (LL i=n;i;i/=pi) k+=i/pi;
for (LL i=m;i;i/=pi) k-=i/pi;
for (LL i=n-m;i;i/=pi) k-=i/pi;
ans=a*inv(b,pk)%pk*inv(c,pk)%pk*fast_pow(pi,k,pk)%pk;
return ans*(Mod/pk)%Mod*inv(Mod/pk,pk)%Mod;
}
int main()
{
scanf("%I64d%I64d%I64d",&n,&m,&MOD);
for (LL x=MOD,i=2;i<=MOD;++i)
if (x%i==0)
{
LL pk=1LL;
while (x%i==0) pk*=i,x/=i;
ans=(ans+C(n,m,MOD,i,pk))%MOD;
}
printf("%I64d\n",ans);
}