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

博客图片都飞了,所以看的时候请多多担待。

中国剩余定理是数论中的一个关于一元线性同余方程组的定理,说明了一元线性同余方程组有解的准则以及求解方法。也称为孙子定理。

本文大部分使用的内容来自维基百科。

中国剩余定理说明:

这里写图片描述
题意:给出你n个ai和mi,最后让求出x的最小值是多少。

假设整数m1, m2, … , mn其中任两数互质,则对任意的整数:a1, a2, … , an,方程组 (S)有解,并且通解可以用如下方式构造得到:

1.设是整数m1, m2, … , mn的乘积,并设
,即 是除了mi以外的n − 1个整数的乘积。

2.设为模的数论倒数:

3.方程组(S)的通解形式为:

在模 M的意义下,方程组 (S)只有一个解:

**注:**对任何,由于,所以说明存在整数 使得这样的叫做 模 的数论倒数。

具体证明可以参照wiki 这里写链接内容

例子也可以看wiki中的“物不知数”。

以下给出一般情况下也就是整数m1, m2, … , mn其中任两数互质情况下的模板:

关于扩展欧几里得可以看以前的文章这里是传送门哦~

代码1:

m[]任意两个互质
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
const int N=1e6+10;
const LL Me=1e9+7;
const int inf=0x3f3f3f3f;

int a[N],m[N];

LL exgcd(LL a,int b,LL &x,LL &y)
{
    if(a==0&&b==0)
        return -1;
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    LL d=exgcd(b,a%b,y,x); //回代 注意这里的与扩展gcd的不同
    y-=a/b*x;
    return d;
}



LL CRT(int n)
{
    LL M=1;
    for(int i=0;i

拓展:

中国剩余数定理是适用于n个mi两两互质的情况的,如果不互质呢,下面就是一个转换:
模不两两互质的同余式组可化为模两两互质的同余式组,再用孙子定理直接求解。
84=22×3×7,160=25×5,63=32×7,由推广的孙子定理可得 与同解。

注意求解过程中应先检查同余式组上是否存在矛盾,存在矛盾的同余式组无解。

证明过程:

中国剩余定理(又称 孙子定理)_第1张图片

代码2:

#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
const int N=1e6+10;
const LL Me=1e9+7;
const int inf=0x3f3f3f3f;

int a[N],m[N];

LL exgcd(LL a,int b,LL &x,LL &y)
{
    if(a==0&&b==0)
        return -1;
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    LL d=exgcd(b,a%b,y,x); //回代 注意这里的与扩展gcd的不同
    y-=a/b*x;
    return d;
}



LL CRT(int n)
{
    if(n==1)
    {
        if(m[0]>a[0])
            return a[0];
        else
            return -1;
    }
    LL x,y,d;
    for(int i=1; i

你可能感兴趣的:(acm算法)