中国剩余定理(孙子定理)

“中国剩余定理”是公元5-6世纪、我国南北朝时期的一部著名算术著作《孙子算经》中的一个“物不知数”的解法问题:今有物不知其数,三三数之剩二,

五五数之剩三,七七数之剩二。问物几何?答曰:二十三。

根据上面我们可以得到一组式子:

X ≡ 2  (mod 3)

X ≡ 3  (mod 5)

X ≡ 2  (mod 7)

即:

X % 3 = 2

X % 5 = 3

X % 7 = 2

那么我们设   X = t1 * a + t2 * b + t3 * c

继续设

a ≡ 1  (mod 3)                          b ≡ 0  (mod 3)                         c ≡ 0  (mod 3)

a ≡ 0  (mod 5)                          b ≡ 1  (mod 5)                         c ≡ 0  (mod 5)

a ≡ 0  (mod 7)                          b ≡ 0  (mod 7)                         c ≡ 1  (mod 7)

a = LCM(5,7) * p(a%3=1)     b = LCM(3,7)*p(b%5=1)       c = LCM(3,5)*p(c%7=1)

= 35 * 2 = 70                           = 21 * 1 = 21                           = 15 * 1 = 15

那么我们就可以根据相对应的颜色得到t1 = 2, t2 = 3, t3 = 2

所以 X = 2a + 3b + 2c = 2 * 70 + 3 * 21 + 2 * 15 = 233

233是X的一个解,通解是 X = 233 + gcd(3,5,7)*k = 233 + 105*k

这些a、b、c(下面同称为Ni)该如何求呢(除数3、5、7统称为mi)

X ≡ y1  (mod m1)

X ≡ y2  (mod m2)

X ≡ y3  (mod m3)

...

X ≡ an  (mod mn)

设X = N1 * y1 + N2 *y2 + N3 * y3 + ... + Nn * yn;

设  Ni能够被m1、m2、m3、.... 、mi-1、 mi + 1、... 、mn整除,但就是不能被mi整除且Ni%mi = 1

设  Ni = LCM(m1, m2, m3, ..., mn) / mi * x  = mi * y + 1, 要求Ni就必须得求x

上面式子可以转化为  LCM(m1, m2, m3, ..., mn) / mi * x + (- mi) * y = 1

转化之后的式子就是扩展欧几里德了, 这样就可以求出x

模板:

int CRT(int a[], int b[], int n)
{//a[i]表示除数,b[i]表示余数
    int M = 1, N, ans = 0, x, y;
    for(int i = 0 ; i < n ; i++)
        M *= a[i];//因为除数两两互质,所以最小公倍数就是其乘积
    for(int i = 0 ; i < n ; i++)
    {
        N = M / a[i];
        gcd(N, a[i], x, y);//利用扩展欧几里德求x
        ans += N * x * b[i];
    }
    return ans % M;
}
时间: 2024-10-07 01:38:14

中国剩余定理(孙子定理)的相关文章

中国剩余定理详解

中国剩余定理 孙子算经里有这样一个问题:"今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?" 翻译成现在的数学问题就是 x%3 == 2,x%5 == 3,x%7 ==  2,求x 的值: 遇到这这样一个问题很多C语言初学者不禁会想到用暴力可以算出来,还要这样一个定理干嘛? 如果数据相当大呢?计算机就会计算相当困难.然而这个问题早早的就被孙子解决了. 求出3,5,7 两两中的最小公倍数lcm,k*lcm与另一个数mod等于1(找出一个符合条件的k): 用k*lcm*

Lucas定理 中国剩余定理 数论

逆元: 若 a*b=1(%p) 则a是b在%p意义下的逆元.  则在%p意义下  一个数 除以a就等价于乘b 两种求逆元方法:1.若p为质数时,则有性质则a^(p-1)=1(%p) .   即a*a^(p-2)=1(%p).   所以a的逆元就是a^(p-2)  2.exgcd(a,b,x,y) 可求 ax+by=c=gcd(a,b)  若a,b互质 则可求a%b下的逆元 Lucas定理:{ 求C(n,m)在%p下的值    (p是质数)    -- Lucas(n,m,p)=c(n%p,m%p

hdu 5446(2015长春网络赛J题 Lucas定理+中国剩余定理)

题意:M=p1*p2*...pk:求C(n,m)%M,pi小于10^5,n,m,M都是小于10^18. pi为质数 M不一定是质数 所以只能用Lucas定理求k次 C(n,m)%Pi最后会得到一个同余方程组x≡B[0](mod p[0])x≡B[1](mod p[1])x≡B[2](mod p[2])......解这个同余方程组 用中国剩余定理 Sample Input19 5 23 5 Sample Output6 1 # include <iostream> 2 # include <

SDOI 2010--古代猪文(Lucas算法&amp;费马小定理&amp;中国剩余定理)

发现几乎每次数论题洛谷总是让我TLE一个点.... 附图: 最后那个点优化了很久终于过了.... 题意 iPig在大肥猪学校图书馆中查阅资料,得知远古时期猪文文字总个数为N.当然,一种语言如果字数很多,字典也相应会很大.当时的猪王国国王考虑到如果修一本字典,规模有可能远远超过康熙字典,花费的猪力.物力将难以估量.故考虑再三没有进行这一项劳猪伤财之举.当然,猪王国的文字后来随着历史变迁逐渐进行了简化,去掉了一些不常用的字. iPig打算研究古时某个朝代的猪文文字.根据相关文献记载,那个朝代流传的猪

ACM-ICPC 2015 Changchun Preliminary Contest J. Unknown Treasure (卢卡斯定理+中国剩余定理)

题目链接:https://nanti.jisuanke.com/t/A1842 题目大意:给定整数n,m,k,其中1≤m≤n≤1018,k≤10, 然后给出k个素数,保证M=p[1]*p[2]……*p[k]≤1018,p[i]≤105 求C(n,m)%(p[1]*p[2]……*p[k]) 解题思路:因为模数太大,所以我们先用卢卡斯定理求出对每个素数的模,然后再通过中国剩余定理就可以求得对它们的乘积的模. 代码: #include<bits/stdc++.h> using namespace s

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

中国剩余定理(CRT) 我好蔡啊 不学这个东东我连任意模数\(NTT\)都学不了 问题 中国剩余定理用于求解同余方程组 \[ \left\{ \begin{aligned} x≡a_1(\mod m_1)\x≡a_2(\mod m_2)\......\x≡a_k(\mod m_k) \end{aligned} \right. \] 其中\(m_1,m_2,...,m_k\)两两互质 求\(x\)的最小非负整数解 定理 令\(M=\prod_{i=1}^km_i\),也就是它们的最小公倍数 设\(

【Lucas定理/费马小定理/中国剩余定理/扩展欧几里得】[BZOJ 1951] 古代猪文

[Description] 求 [Solution] 容易得到, 所以,重点在怎么求 如果是p-1是个质数,我们可以用sqrt(n)的时间枚举所有d,用Lucas定理分别计算求和即可. 但是我们发现p-1=2*3*4679*35617,并不是一个质数,所以Lucas定理不能用了吗?并不,我们可以算出这个合式分别对2.3.4679.35617的模值,写出四个同余方程,再用孙子定理求解即可.注意特判g==p的情况,此时费马小定理不成立,ans=0. [Code] #include<cmath> #

hdu 5446 Unknown Treasure (Lucas定理+中国剩余定理+快速乘)

题意:c( n, m)%M    M = P1 * P2 * ......* Pk (其中Pk是素数) 思路:Lucas定理中C(n,m)%M,M必须是素数,当M不是素数时,我们可以把它拆成素数的乘积 如果x=C(n,m)%M ,M=p1*p2*..*pk;  a[i]=Lucas(n,m)%pi: xΞa[1](mod p1) xΞa[2](mod p2) ... xΞa[k](mod pk) 用中国剩余定理就可以把x求出来 注意到这道题ll*ll 由于计算机底层设计的原因,做加法往往比乘法快

hdu1573-X问题-(扩展欧几里得定理+中国剩余定理)

X问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8416    Accepted Submission(s): 3066 Problem Description 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mod

visit(卢卡斯定理&amp;&amp;中国剩余定理)

如此显然的组合数我把它当DP做,我真是.... 因为起点终点已经确定,我们发现如果我们确定了一个方向的步数其他方向也就确定了 组合数做法1: 设向右走了a步,然后向左走了b=a-n步,设向上为c,向下为d; c+d=t-a-b; c-d=m; 求出c=(t+n+m-i-i)/2;if(c%2)continue; (因为如果c不能整除2表示向右多走的步数无法走回) 组合数做法2: 参考nc神犇的做法 首先设水平方向一共走了i步,所以(i-n)/2为水平方向上返回的步数, 竖直方向上步数t-i,中同