中国剩余定理

数论太弱啦,还是来点基础的吧..终于不用担心小学奥数题不会做啦……
中国剩余定理是解决线性模方程组的东西

xa1(modp1)

xa2(modp2)

.....

考虑将两个方程合并
x=k1p1+a1
x=k2p2+a2
k1p1+a1=k2p2+a2

k1p1k2p2=a2a1

然后用拓展欧几里得算法求出 k1,k2 ,然后求出 x
合并出来的新的方程就是
yx(modp1p2gcd(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();
}

你可能感兴趣的:(数论)