中国剩余定理和扩展中国剩余定理

 

#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;

void exgcd(ll a,ll b,ll &g,ll &x,ll &y)
{
    if(b==0)
    {
        g=a;
        x=1;y=0;
    }
    else {exgcd(b,a%b,g,y,x);y-=(a/b)*x;}
}

ll China(int n,ll *m,ll *a){
    ll M=1,d,y,x=0;
    for(int i=0;i<n;i++) M*=m[i];
    for(int i=0;i<n;i++){
        ll w=M/m[i];
        exgcd(m[i],w,d,d,y);
        x=(x+y*w*a[i])%M;
    }
    return (x+M)%M;
}

ll m[15],a[15];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lld%lld",&m[i],&a[i]);
    printf("%lld",China(n,m,a));
} 

 除数不全为素数

#include <iostream>//hdu3579
#include <cstdio>
#include <string>
#define ll long long

using namespace std;

const int maxn=1e5+10;

int T,n;
ll m[maxn],r[maxn];

ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b){x=1;y=0;return a;}
    ll re=exgcd(b,a%b,x,y);ll tmp=x;
    x=y;y=tmp-(a/b)*y;
    return re;
}

ll work()
{
    ll M=m[1],R=r[1],x,y,d;
    for(int i=2;i<=n;i++){
        d=exgcd(M,m[i],x,y);
        if((r[i]-R)%d) return -1;
        x=(r[i]-R)/d*x%(m[i]/d);
        R+=x*M;
        M=M/d*m[i];
        R%=M;
    }
    return R>0?R:R+M;
}


int main()
{
    scanf("%d",&T);
    for(int k=1;k<=T;k++){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lld",&m[i]);
        for(int i=1;i<=n;i++) scanf("%lld",&r[i]);
        printf("Case %d: %lld\n",k,work());
    }
    return 0;
}

 

posted @ 2018-10-08 20:37  Somnus、M  阅读(219)  评论(0编辑  收藏  举报