中国剩余定理拓展

#include <stdio.h>                //互质
int exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int chinese_remainder()
{
    int i,d,x,y,M,m=1,sum=0;
    for(i=0;i<n;i++)
        m*=prime[i];
    for(i=0;i<n;i++)
    {
        M=m/prime[i];
        d=exgcd(M,prime[i],x,y);
        sum=(sum+x*M*a[i])%m;
    }
    return (m+sum%m)%m;
}
#include <stdio.h>          //非互质
#include <string.h>
#define min(a,b) a>b?b:a
#define ll long long
ll read()
{
    ll s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
ll a[100001],m[100001];
ll exgcd(ll a,ll b,ll &x,ll&y)
{
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
ll quick_mul(ll x,ll y,ll p)
{
	return (x*y-(ll)((long double)x*y/p)*p+p)%p;
}
ll chinese_remainder2(int n)
{
    ll a1=a[0],m1=m[0];
    for(int i=1;i<n;i++)
    {
        ll a2=a[i],m2=m[i];
        ll c=a2-a1;
        ll x,y;
        ll d=exgcd(m1,m2,x,y);
        if(c%d)
            return 0;
        x=quick_mul(x,c/d,m2/d);
        a1+=x*m1;
        m1=m1/exgcd(m1,m2,x,y)*m2;
    	a1=(a1%m1+m1)%m1;
    }
    return a1;
}
int main()
{
    int n=read();
    for(int i=0;i<n;i++)
        m[i]=read(),a[i]=read();
    ll ans=chinese_remainder2(n);
    printf("%lld",ans);
}
发布了88 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44879687/article/details/102335046