码迷,mamicode.com
首页 > 其他好文 > 详细

excrt(拓展中国剩余定理)

时间:2019-07-23 13:33:59      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:read   psu   c++   exgcd   getchar   ==   amp   html   getch   

对于一个同余方程

对于第一个和第二个式子

则有:

ans=a1?+k1?n1?

ans=a2?+k2?n2?

就有:

a1?+k1?n1?=a2?+k2?n2?

k1?n1?k2?n2?=a2?a1?

故我们设c=a2?a1? 再变化一下形式就有:

k1?n1?+(k2?)n2?=c

令 gcd=gcd(n1?,n2?)

这样我们就可以通过exgcd来求出一组解x1?,y1?

满足 x1?n1?+y2?n2?=gcd

故:x1?d/gn1?+y2?d/gn2?=gc/gcd

则: k1?=x1?∗c/gcd,k2?=y1?c/gcd

从而得到一组通解((k1+q)*n1+(k2-p)*n2=c)

k1?=k1+q=k1?+n2/gcdT

k2?=k2-p=k2?n1/gcdT

要使所求得的解最小且为正整数则可以根据 k1? 的通解形式求得

mink1?=(k1?%(n2?/gcd)+n2?/gcd)%(n2?/gcd)

再带入ans=a1?+mink1?n1? 得到 ans

令 A 为合并后的 a , N 为合并后的 n

所以N=lcm(n1?,n2?)=n1?n2?/gcd

根据ansA (mod N) 且 ans 是满足该式子最小的值

得到: A=ans

代码

#include<bits/stdc++.h>
using namespace std;
#define ll __int128
ll ans,a[100010],n[100010],N,a1,a2,n1,n2,c,gcd,x,y;
long long read()
{
    ll f=1,x=0;
    char ss=getchar();
    while(ss<0||ss>9){if(ss==-)f=-1;ss=getchar();}
    while(ss>=0&&ss<=9){x=x*10+ss-0;ss=getchar();}
    return f*x;
}
void exgcd(ll aa,ll bb,ll &gcd,ll &x,ll &y)
{
    if(!bb) 
    {
        gcd=aa;
        x=1,y=0;
        return;
    }
    exgcd(bb,aa%bb,gcd,x,y);
    ll tr=x;
    x=y;
    y=tr-aa/bb*y;
}
long long zs()
{
    a1=a[1],n1=n[1];
    for(ll i=2;i<=N;i++)
    {
        a2=a[i],n2=n[i];
        c=a2-a1;
        exgcd(n1,n2,gcd,x,y);//n1*x+n2*y=gcd(n1,n2)的解 
        if(c%gcd==0) 
        {
            ll k1=x*c/gcd;//n1*k1+n2*k2=c的解 
            ll mink1=(k1%(n2/gcd)+(n2/gcd))%(n2/gcd);//k1通解:k1=k1+(n2/gcd)*t
            ans=mink1*n1+a1;//这2个方程的解 
            //合并2个方程 
            n1=(n1*n2)/gcd;
            a1=ans;
        }
        else return -1;
    }
    return ans;
}
int main()
{
    N=read();
    for(ll i=1;i<=N;i++)
        n[i]=read(),a[i]=read();
    cout<<zs();
    return 0;
}

部分参考来自https://www.luogu.org/blog/sumijie/solution-p4777

excrt(拓展中国剩余定理)

标签:read   psu   c++   exgcd   getchar   ==   amp   html   getch   

原文地址:https://www.cnblogs.com/oierglh/p/11230965.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!