中国剩余定理

来源:互联网 发布:网络歌手伤感歌曲 编辑:程序博客网 时间:2024/06/05 00:28

作用

给出如下模方程组:

xr1(mod m1)xr2(mod m2)xrk(mod mk)

其中mi(1<=i<=k)两两互质,求解满足的最小x。

中国剩余定理也称孙子定理,可以高效求解上述问题。
ps:好像几乎不考中国剩余定理=_=

方法

举个孙子算经里的例子:(今有物不知其数,三三数之余二,五五数之余三,七七数之余二,问物几何?)

x2(mod 3)x3(mod 5)x2(mod 7)

定理①:当axb(mod m)时,axcbc(mod m),这个很显然。
还可以得出x0+105k(kZ,k>=0均为该问题的解(x0是最小解,105是3,5,7的最小公倍数)。

所以我们可以把原来的式子转变为这样:

x1(mod 3)x0(mod 5)x0(mod 7)x0(mod 3)x1(mod 5)x0(mod 7)x0(mod 3)x0(mod 5)x1(mod 7)

分别求解这三个模方程组的答案(x1,x2,x3),那么最后的答案x就等于2x1+3x2+5x3模105。

我们来看第一个方程组,为了让x满足x0(mod 5)x0(mod 7),我们需要保证x是lcm(5,7)=35的倍数,设x=35*y,那么这个方程组简化为35y1(mod 3),也就变成了普通的模方程,用扩展欧几里得就可以求解出y=2即x=70。第二个方程组可以求解出x=21,第三个方程组可以求解出x=15。

那么最小解就是:(2*70+3*21+5*15) mod 105=23。(三人同行七十稀,五树梅花廿一枝,七子团圆月正半,除百零五便可知。)

有了这个例子,就不难给出代码了。不过我感觉中国剩余定理适用范围并不是很广,因为我们要取所有mi的最小公倍数即Πmimi随便大一点就炸掉了,如果要写高精度需要除法,代码复杂度就很高了=_=。

模板

int China(int *w,int *m,int n){    int lcm=1,ans=0;for (int i=1;i<=n;i++) lcm*=m[i];    for (int i=1;i<=n;i++)    {        int x,y,M=lcm/m[i];exgcd(M,m[i],x,y);        ans=(ans+x*M*w[i])%lcm;    }    return (ans+lcm)%lcm;}

模板题

POJ1006,题解传送门。

原创粉丝点击