【知识点】中国剩余定理(CRT)
【用途】解决一元线性同余方程组
【板子(m之间互素)】
/* 中国剩余定理板子(基础) 设余数为c[i],模数为m[i],令M为m[i]之和 那么最终答案就是c[i](M/m[i]) inv((M/m[i]),m[i])之和modM 解是唯一的,而且由于每个mod都m个不同的情况,所以恰好可以涵盖所有情况。 */ ll c[maxn],m[maxn],M;//i从1开始 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; } ll getInv(ll a,ll mod) { ll x,y,d; d=exgcd(a,mod,x,y); return d==1?(x%mod+mod)%mod:-1; } ll CRT(int n) { M=1; for(int i=1;i<=n;i++)M*=m[i]; ll ret=0; for(int i=1;i<=n;i++) ret=(ret+c[i] * (M/m[i]) %M * getInv(M/m[i],m[i]) )%M; return ret; }
【板子(扩展)】
/* 中国剩余定理板子(扩展) 在mo数不两两互素之时 */ ll m[maxn],c[maxn];//从1开始 ll gcd(ll a,ll b) { return !b?a:gcd(b,a%b); } 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; } ll getInv(ll a,ll mod) { ll x,y; ll d=exgcd(a,mod,x,y); return d==1?(x+mod)%mod:-1; } ll exCRT(int n) { ll m1,m2,c1,c2,d; for(int i=2;i<=n;i++) { m1=m[i-1],m2=m[i],c1=c[i-1],c2=c[i]; d=gcd(m1,m2); if((c2-c1)%d)return -1;//此时无法合并 m[i] = m[i-1] * m[i] / d; c[i] = (c2-c1)/d * getInv(m1/d,m2/d) % ( m2 / d ) * m1 + c1; c[i] = ( c[i] % m[i] + m[i] ) % m[i]; } return c[n]; }
【证明】
我还没学啦,详细看链接
https://www.cnblogs.com/MashiroSky/p/5918158.html
【习题】
hdu 1573
【参考链接】
https://blog.csdn.net/xiaoming_p/article/details/79672049