您的位置:首页 > 其它

中国剩余定理

2016-02-27 16:58 288 查看
数论太弱啦,还是来点基础的吧..终于不用担心小学奥数题不会做啦……

中国剩余定理是解决线性模方程组的东西

x≡a1(modp1)

x≡a2(modp2)

.....

考虑将两个方程合并

x=k1∗p1+a1

x=k2∗p2+a2

k1∗p1+a1=k2∗p2+a2

k1∗p1−k2∗p2=a2−a1

然后用拓展欧几里得算法求出k1,k2,然后求出x

合并出来的新的方程就是y≡x(modp1∗p2gcd(p1,p2))

然后一直不断合并下去就是最终结果

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[20],p[20];
int n;
void ex_gcd(ll x,ll y,ll &a,ll &b,ll &gcd)
{
if(x==0)
{
gcd=y;a=0;b=1;
return;
}
ex_gcd(y%x,x,b,a,gcd);
a-=b*(y/x);
}
ll China()
{
ll na=a[1],np=p[1];
for(int i=2;i<=n;i++)
{
ll gcd,k1,k2;
ex_gcd(np,p[i],k1,k2,gcd);
if(abs(na-a[i])%gcd)return -1;
k1=k1%(p[i]/gcd);
k1*=(a[i]-na)/gcd;
k1=k1%(p[i]/gcd);
if(k1<0)k1+=p[i]/gcd;
na=k1*np+na;
np=np*p[i]/gcd;
}
//cout << na <<" "<< np << endl;
return na%np;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>p[i]>>a[i];
cout<<China();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数论