中国剩余定理

相信诸位如果学过小学奥数,一定知道如下这个方程组:
2≡1 mod(3)

9≡2 mod(7)

8≡8 mod(11)

.

.

.

n≡k mod(p)n,k<p且p为素数且互不相同

我们的目的很简单,就是求出满足如上方程的最小整数

然后这就是中国剩余定理qwq。。。

好吧,不扯了,让我们开始写代码吧

实现方法1:暴力枚举

先排序,从头开始,从满足第一个方程的最小数开始,每次加上当前被满足的几个方程的p的乘积(这样每次加上的都是前面几个数的倍数,被加上的部分取模后为0,不会影响已经满足的答案),如果满足当前方程,则更新乘积,求解下一组方程

优点:

既好想,也好写。

缺点:

出题人随手就能卡住,复杂度较高(比如说两个素数分别为2和212370440130137957),电脑这辈子都算不出来

先看一道例题:

曹冲养猪

这种思路是能A的

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long a,b,c,d,e,f,g,kkk,n;
struct zzzz{
    int x,y,z;
}ltt[15];
bool cmp(zzzz s,zzzz t)
{
    return s.x>t.x;
}
int main()
{
    cin>>n;
    kkk=1;
    for(a=1;a<=n;a++)
    {
        cin>>ltt[a].x>>ltt[a].y;
    }
    sort(ltt+1,ltt+n+1,cmp);
    kkk=ltt[1].x;
    g=ltt[1].y;
    f+=2;
    while(f<=n)
    {
        while(1)
        {
            if(g%ltt[f].x==ltt[f].y)
            {
                kkk=kkk*ltt[f].x;
                f++;
                break;
            }
            g=g+kkk;
        }
    }
    cout<<g;
}

上面不是复杂度太高么?那怎么办呢?

现在我们就要用到另一个东西——不定方程

 上面的任意两个方程组可以转变为:

a*x1+p1=b*x2+p2

那么我们移项通分,可以得到:

(p3=p2-p1)

a*x1-b*x2=p3;

这是一个二元一次方程,求解即可

原文地址:https://www.cnblogs.com/ztz11/p/9279214.html