Extended_gcd 的应用:中国剩余定理。

来源:互联网 发布:720音频恢复软件 编辑:程序博客网 时间:2024/04/29 18:46


这个文章总结参考http://blog.csdn.net/only_air/article/details/51017950,我哥们总结得很认真。


讲中国剩余定理之前,介绍一些应该掌握的知识:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

线性同余式:

这里写图片描述

看有没有解和解的个数的方法:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述


现在讲一下中国剩余定理:对于被取模的数必须互质才能运用这个方式去求满足同模线性方程组的数X

中国剩余定理给出了以下的一元线性同余方程组:

这里写图片描述

假设整数m1,m2, … ,mn两两互质,则对任意的整数:a1,a2, … ,an,
方程组有解。

求法如下:

这里写图片描述,是被取模的所有数的乘积

这里写图片描述,是除了这个数所有数乘积,

这里写图片描述这里写图片描述这里写图片描述的数论倒数,数论倒数满足:这里写图片描述

则方程组的通式是这里写图片描述

在模M的情况下只有一个解:这里写图片描述

接下来详细讲一下数论倒数:

数论倒数的概念,
如果两个数a和b,它们的乘积关于模m余1,那么我们称它们互为关于模m的数论倒数.比如这里写图片描述

为什么要使余数为1:是为了要求余数2的话,只要乘以2就可以,要求余数为3的话,只要乘以3就可以!

Mi * ti mod mi = 1 => Mi * ti + mi * y = 1,所以解出这个同模方程式就可以把每个ti求出来。

POJ1006Biorhythms生理周期

题意就是m1=23,m2=28,m3=33;

输入p,e,i,d三个数,前三个代表的是这三个周期开始的时间,需要求在d之后哪天会出现三个周期在同一天。

由题意,得三个同模方程: X p (mod m1); X e(mod m2); Xi (mod m3);

所以由先求出各个对应的 ti,求出最小的X;

不过最后是是要大于d的X,所以进行处理一下就行了


#include <iostream>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;ll x,y;ll Extended_gcd(ll a,ll b,ll &x,ll &y){    if(b==0)    {        x=1;        y=0;        return a;    }    ll d=Extended_gcd(b, a%b,x,y);    ll t=x;    x=y;    y=t-a/b*y;    return d;}int main(){    ll a[10],d;    int k=0;    while(scanf("%I64d%I64d%I64d%I64d",&a[1],&a[2],&a[3],&d) != EOF && (a[1] != -1||a[2]!= - 1||a[3] != -1||d != -1))    {        ll m[10];        ll M=1;        m[1]=23;        m[2]=28;        m[3]=33;        for(int i=1; i<= 3;i ++)        {           M*=m[i];        }        ll ans=0;        for(int i=1;i <= 3;i++)        {            Extended_gcd(M/m[i],m[i],x,y);            ans+=(x*M/m[i]*a[i])%M;        }        ans=ans%M;        cout<<"Case "<<++k<<": the next triple peak occurs in ";        if((ans%M+M-d)%M)        cout<<(ans%M+M-d)%M<<" days."<<endl;        else cout<<M<<" days."<<endl;    }    return 0;}


FZU1402猪的安家

这是裸的模板了:

//#include<bits/stdc++.h>#include<iostream>#include<cmath>#include<cstdio>using namespace std;typedef long long ll;const int maxn = 100000+10;ll x,y;ll ex_gcd(ll a,ll b,ll &x, ll &y){    if(b==0)    {        x=1;        y=0;        return a;    }    ll d=ex_gcd(b,a%b,x,y);    ll t=x;    x = y;    y = t- a /b *y;    return d;}int main(){    int n;    ll a[100],b[100];    while(scanf("%d",&n) != EOF)    {        ll M=1;        for(int i=1 ;i <= n ;i++)        {            scanf("%I64d%I64d",&a[i],&b[i]);            M*=a[i];        }        ll ans=0;        for(int i=1 ;i <= n; i++)        {            ex_gcd(M/a[i],a[i],x,y);            ans+=(x%M*M/a[i]*b[i])%M;            ans %=M;        }        cout<<(ans%M + M) % M<<endl;    }}


还有的就是同模的数不是互质的一些求法了,这样的话就不适用于中国剩余定理了:不过现在还是不懂,先留在这吧:



0 0
原创粉丝点击