『线性同余方程和中国剩余定理』
Posted parsnip
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『线性同余方程和中国剩余定理』相关的知识,希望对你有一定的参考价值。
<更新提示>
<第一次更新>
<正文>
线性同余方程
定义
给定整数(a,b,m),对于形如(axequiv b(mod m))的同余方程我们称之为一次同余方程,即线性同余方程。
解线性同余方程
对于此类方程,我们可以用如下方法快速的求解。
[
axequiv b(mod m)?m|ax-b
]
不妨设(-ym=ax-b),则可以将方程改写为(ax+my=b),该不定方程可以使用扩展欧几里得算法快速地求解(详见『扩展欧几里得算法 Extended Euclid』)。
对于(gcd(a,m) ot |b)的情况,也可以直接判定为原方程无解。
对于使用扩展欧几里得算法求解出来的一个解(x_0),所有模(m)意义下与(x_0)同余的整数都是方程的解。通常来说,我们需要求解最小非负整数解时,可以使用取模操作让(x)落在(0)到(m-1)的范围内,就得到了最小解。
同余方程(NOIP2012)
Description
求关于 x 的同余方程 ax≡1(mod b) 的最小正整数解。
Input Format
输入只有一行,包含两个正整数 a,b,用一个空格隔开。
Output Format
输出只有一行,包含一个正整数 x0,即最小正整数解。输入数据保证一定有解。
Sample Input
3 10
Sample Output
7
解析
模板题,将方程化为(ax+by=1),用扩展欧几里得算法求解。由于数据保证(bgeq2),所以不存在(x=0)的解,利用取模操作就能保证得到的解是最小整数解。
(Code:)
#include<bits/stdc++.h>
using namespace std;
inline long long Exeuclid(long long a,long long &x,long long b,long long &y,long long c)
{
if (b==0){x=c/a,y=0;return a;}
else
{
long long p=Exeuclid(b,x,a%b,y,c);
long long x_=x,y_=y;
x=y_;y=x_-a/b*y_;
return p;
}
}
long long A,B,X,Y;
int main(void)
{
scanf("%lld%lld",&A,&B);
Exeuclid(A,X,B,Y,1);
printf("%lld
",(X%B+B)%B);
return 0;
}
中国剩余定理
描述
对于形如
[ egin{cases} x equiv a_1(mod m_1) \\ x equiv a_2(mod m_2) \\ ... \\ x equiv a_n(mod m_n) end{cases} ]
(n)个线性同余方程组成的线性同余方程组,如果有模数(m_1,m_2,...,m_n)两两互质,则方程组一定有解,解为(x=sum_{i=1}^{n}a_iM_it_i)。
其中,(m=prod_{i=1}^nm_i),(M_i=frac{m}{m_i}),(t_i)为线性同余方程(M_it_i equiv 1(mod m_i))的一个解。
证明:
由于(t_i)为线性同余方程(M_it_i equiv 1(mod m_i))的一个解,所以对于(forall i,a_iM_it_i equiv a_i(mod m_i))成立,又因为(M_i)是除了(m_i)以外所有模数的倍数,即对于(forall k
ot =i,a_iM_it_i equiv 0(mod m_k)),所以解(x=sum_{i=1}^{n}a_iM_it_i)对方程(x equiv a_i(mod m_i))也成立,故该解对于每一个方程都成立。
对于该同余方程组,其通解可以表示为(x+km(kin Z)),对于最小非负整数解,也是通过取模(m)的操作就可以了。
曹冲养猪
Description
自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。
举个例子,假如有16头母猪,如果建了3个猪圈,剩下1头猪就没有地方安家了。如果建造了5个猪圈,但是仍然有1头猪没有地方去,然后如果建造了7个猪圈,还有2头没有地方去。
你作为曹总的私人秘书理所当然要将准确的猪数报给曹总,你该怎么办?
Input Format
第一行包含一个整数n (n <= 10) – 建立猪圈的次数,
解下来n行,每行两个整数ai, bi( bi <= ai <= 1000), 表示建立了ai个猪圈,有bi头猪没有去处。你可以假定ai,aj互质.
Output Format
输出包含一个正整数,即为曹冲至少养母猪的数目。
Sample Input
3
3 1
5 1
7 2
Sample Output
16
解析
中国剩余定理模板题,我们直接利用(Exeuclid)算法和线性同余方程的知识,解出(t_i),然后构造最小非负整数解即可。
(Code:)
#include<bits/stdc++.h>
using namespace std;
#define mset(name,val) memset(name,val,sizeof name)
const int N=12;
long long a[N],m[N],M[N],t[N],n,m_,ans;
inline void input(void)
{
scanf("%lld",&n);
for (int i=1;i<=n;i++)
scanf("%lld%lld",&m[i],&a[i]);
}
inline long long Exeuclid(long long a,long long &x,long long b,long long &y,long long c)
{
if (b==0){x=c/a,y=0;return a;}
else
{
long long p=Exeuclid(b,x,a%b,y,c);
long long x_=x,y_=y;
x=y_;y=x_-a/b*y_;
return p;
}
}
inline void china(void)
{
m_=1;
for (int i=1;i<=n;i++)
m_*=m[i];
for (int i=1;i<=n;i++)
M[i]=m_/m[i];
for (int i=1;i<=n;i++)
{
long long y;
Exeuclid(M[i],t[i],m[i],y,1);
ans += a[i]%m_ * M[i]%m_ * t[i]%m_;
ans %= m_;
}
}
int main(void)
{
input();
china();
printf("%lld
",(ans%m_+m_)%m_);
return 0;
}
<后记>
后记>正文>第一次更新>更新提示>以上是关于『线性同余方程和中国剩余定理』的主要内容,如果未能解决你的问题,请参考以下文章