【数学】【数论】中国剩余定理

写在前面

  记录了个人的学习过程,同时方便复习

  • 中国剩余定理

【物不知数】是中国古代著名算题

原载《孙子算经》卷下第二十六题:

“今有物不知其数,三三数之剩二;五五数之剩三;七七数之剩二。问物几何?”

当时虽已有了答案23,但它的系统解法是秦九韶在《数书九章·大衍求一术》中给出的

中国剩余定理是中国古算中最有独创性的成就之一,属现代数论中的一次同余式组问题

——bia度百科

  有x个物件,三个三个数剩2个,五个五个位数剩3个,七个七个数剩2个

  那么就是求解以下同余方程:

    x ≡ 2 (MOD 3)

    x ≡ 3 (MOD 5)

    x ≡ 2 (MOD 7)

  可以用分治的思想来做

  先求得这样的三个数,使得对于每个模数而言,仅有模它得到的余数为1

(注意,这样的解法仅在模数两两互质的情况下成立)

    x1 ≡ 1 (MOD 3)  x2 ≡ 0 (MOD 3)  x3 ≡ 0 (MOD 3)

    x1 ≡ 0 (MOD 5)  x2 ≡ 1 (MOD 5)  x3 ≡ 0 (MOD 5)

    x1 ≡ 0 (MOD 7)  x2 ≡ 0 (MOD 7)  x3 ≡ 1 (MOD 7)

    就第一组x1的同余方程来说,它的解是5*7*n1

    n1*35 ≡ 1 (MOD 3)

    也就是 n1*2 ≡ 1 (MOD 3)

    n1 == 2,x1 == 70

    同理得到n2 == 1,x2 == 21,n3 == 1,x3 == 15

  因为要求的余数为2,3,2,分别将x1,x2,x3乘上对应的余数

  再把得到的x1*2,x2*3,x3*2加起来就好了,这样的得到的就是一种解

  希望求最小正整数解,把得到的数模上3,5,7的最小公倍数就好了

  推广到其他的情形,需要解这样的一组同余方程

    x ≡ k1 (MOD p1)

    x ≡ k2 (MOD p2)

    ......

    x ≡ kn (MOD pn)

    (其中p1,p2,......,pn之间两两互质)

  求出它们的最大公因数M == ∏ki=1?pi (因为这些数两两互质)

  则对于每一个数p,p与M/p的最大公因数为1

  使用拓展欧几里得算法求出一组x,y,使得M/p*x + p*y ≡ 1 (MOD M)

  留下来x就好,y不用管了

x == (x1*p1*k1 + x2*p2*k2 + ...... + xn*pn*kn) MOD M

  这样就算好啦

  代码如下:

C++:

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 int const MAXN=10010;
 6 int x,y;
 7 int k;//k组同余方程
 8 int a[MAXN];//每个同余方程的余数
 9 int b[MAXN];//每个同余方程的模数
10 int ans;
11 int lcm=1;
12
13 void exgcd(int a,int b)
14 {
15     if(b==0){x=1;y=0;}
16     else{
17         exgcd(b,a%b);
18         int tmp=x;
19         x=y;y=tmp-a/b*y;
20     }
21     return;
22 }
23
24 int main(int argc,char *argv[],char *enc[])
25 {
26     scanf("%d",&k);
27     for(int i=1;i<=k;++i)
28         scanf("%d%d",&b[i],&a[i]);
29
30     for(int i=1;i<=k;++i)
31         lcm*=b[i];
32     for(int i=1;i<=k;++i)
33     {
34         exgcd(lcm/b[i],b[i]);
35         x=(x%b[i]+b[i])%b[i];
36
37         ans=(ans+(lcm/b[i])*x*a[i])%lcm;
38     }
39
40     printf("%d",ans);
41     return 0;
42 }

Java:

 1 import java.io.*;
 2 import java.util.*;
 3
 4 class pony{
 5
 6     static int MAXN=10010;
 7     static int x,y;
 8     static int k;//k组同余方程
 9     static int[] a=new int[MAXN];//每个同余方程的余数
10     static int[] b=new int[MAXN];//每个同余方程的模数
11     static int ans;
12     static int lcm=1;
13
14     static void exgcd(int a,int b)
15     {
16         if(b==0){x=1;y=0;}
17         else{
18             exgcd(b,a%b);
19             int tmp=x;
20             x=y;y=tmp-a/b*y;
21         }
22         return;
23     }
24
25     public static void main(String[] args) throws Exception {
26
27         Scanner cin=new Scanner(System.in);
28
29         k=cin.nextInt();
30         for(int i=1;i<=k;++i)
31         {
32             b[i]=cin.nextInt();
33             a[i]=cin.nextInt();
34         }
35
36         for(int i=1;i<=k;++i)
37             lcm*=b[i];
38         for(int i=1;i<=k;++i)
39         {
40             exgcd(lcm/b[i],b[i]);
41             x=(x%b[i]+b[i])%b[i];
42
43             ans=(ans+(lcm/b[i])*x*a[i])%lcm;
44         }
45
46         System.out.println(ans);
47     }
48 }

因为两两互质,最小公倍数就是这些数的积,我在对唯一分解定理的研究中提到过

  • 拓展中国剩余定理

  以上方法仅仅适用于每个模数两两互质的情况

  但是最常见的情况还是所有模数不满足两两互质

  这样的话,中国剩余定理就不再适用

  需要使用[?]拓展中国剩余定理

原文地址:https://www.cnblogs.com/Antigonae/p/10129122.html

时间: 2024-08-13 12:42:21

【数学】【数论】中国剩余定理的相关文章

数论E - Biorhythms(中国剩余定理,一水)

E - Biorhythms Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Description Some people believe that there are three cycles in a person's life that start the day he or she is born. These three cycles are the

数论总结之 中国剩余定理

背景 我!终于学会孙子定理了!!!!!!!!!!!!!!!!!!!!!!!!!!! 好难啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! QAQ 中国剩余定理 中国剩余定理又名孙子定理. 在了解中国剩余定理之前,我先放出之前终止了我很长时间的懵逼的一段话. 中国剩余定理介绍 在<孙子算经>中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”这个问题称为“孙子问题”,该问题的一般解法国际上称为

acm数论之旅--中国剩余定理

中国剩余定理,又名孙子定理o(*≧▽≦)ツ 能求解什么问题呢? 问题: 一堆物品 3个3个分剩2个 5个5个分剩3个 7个7个分剩2个 问这个物品有多少个 解这题,我们需要构造一个答案 我们需要构造这个答案 5*7*inv(5*7,  3) % 3  =  1 3*7*inv(3*7,  5) % 5  =  1 3*5*inv(3*5,  7) % 7  =  1 这3个式子对不对,别告诉我逆元你忘了(*′?`*),忘了的人请翻阅前几章复习 然后两边同乘你需要的数 2 * 5*7*inv(5*

同余 模算术 中国剩余定理

相关知识点: 1.a≡b(modc),a,b关于模c同余  ,即a modc=b mod c , 等价于a%c=b 2.如果a,b互质(a,b)=1,则可得a关于模b的逆 ax≡1(modb) 3.关于余数的定理: 定理1 :如果被除数加上(或减去)除数的整数倍,除数不变,则余数不变. 定理2 :如果被除数扩大(或缩小)几倍,除数不变,则余数也扩大(或缩小)同样的倍数. 定理3: 如果整数a除以自然数b(b≠0),余数r仍不小于b,则r除以b的余数等于a除以b所得余数.(余数和被除数关于除数同余

hihocode 九十七周 中国剩余定理

题目1 : 数论六·模线性方程组 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:今天我听到一个挺有意思的故事! 小Hi:什么故事啊? 小Ho:说秦末,刘邦的将军韩信带领1500名士兵经历了一场战斗,战死四百余人.韩信为了清点人数让士兵站成三人一排,多出来两人:站成五人一排,多出来四人:站成七人一排,多出来六人.韩信立刻就知道了剩余人数为1049人. 小Hi:韩信点兵嘛,这个故事很有名的. 小Ho:我觉得这里面一定有什么巧妙的计算方法!不然韩信不可能这么快计

转载----POJ 1006 中国剩余定理

本文为转载,源地址:   http://blog.csdn.net/dongfengkuayue/article/details/6461298 POJ 1006   Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 78980   Accepted: 23740 Description Some people believe that there are three cycles in a perso

gcd,扩展欧几里得,中国剩余定理

1.gcd: int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } 2.中国剩余定理: 题目:学生A依次给n个整数a[],学生B相应给n个正整数m[]且两两互素,老师提出问题:有一正整数ans,对于每一对数,都有:(ans-a[i])mod m[i]=0.求此数最小为多少. 输入样例: 1 10 2 3 1 2 3 2 3 5 8 1 2 3 4 5 6 7 8 97 89 67 61 59 53 47 88 12 1 2 3 4 5 6 7 8 9

HDU 1573 X问题 中国剩余定理

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1573 题意:求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mod a[i] = b[i], - (0 < a[i] <= 10). 思路:中国剩余定理的模板题,如果找不到这样的数或者最小的X大于N,输出零. 代码: #include <iostream> #include

POJ 1006 中国剩余定理

[题意]: 给定p,e,i,d,求解 (x + d) % 23 = p (x + d) % 28 = e(x + d) % 33 = i x最小正整数值 [知识点]: 中国剩余定理 [题解]: 典型的 xmodmi = ai模型,其中mi间两两互素.但该题式子较少,也可以直接自己化简带入值. [代码]: 1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #inc

【bzoj3782】上学路线 dp+容斥原理+Lucas定理+中国剩余定理

题目描述 小C所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M).小C家住在西南角,学校在东北角.现在有T个路口进行施工,小C不能通过这些路口.小C喜欢走最短的路径到达目的地,因此他每天上学时都只会向东或北行走:而小C又喜欢走不同的路径,因此他问你按照他走最短路径的规则,他可以选择的不同的上学路线有多少条.由于答案可能很大,所以小C只需要让你求出路径数mod P的值. 输入 第一行,四个整数N.M.T.P. 接下来的T行,每行两个整数,表示施工的路口的坐标. 输出 一