强势看懂--中国剩余定理--不互质--解题模板

先上大佬代码:

#include<iostream>
#include<stdio.h>
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y){
    if(b==0){
        x=1,y=0;
        return a;
    }
    long long q=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return q;
}
int main(){
    long long a1,c1,a2,c2,x,y,t;
    long long n;
    while(cin>>n){
        long long flag=1;
        cin>>a1>>c1;
        for(long long i=1;i<n;i++){
            cin>>a2>>c2;
            long long q=exgcd(a1,a2,x,y);
            if((c2-c1)%q!=0){
                flag=0;
            }
            t=a2/q;
            x=((x*(c2-c1)/q)%t+t)%t;
            //cout<<x;
            c1=c1+a1*x;
            a1=a1*(a2/q);
        }
        if(flag==0){
            cout<<"-1"<<endl;
            continue;
        }
        cout<<c1<<endl;
    }
    return 0;
}

造了一组数据:

n=6;

a[1]=5;a[2]=6;a[3]=7;a[4]=8;a[5]=9;a[6]=10;

c[1]=1;c[2]=2;c[3]=3;c[4]=4;c[5]=5;c[6]=6;

手写测试,写到崩溃,,

在代码上强势贴上牛皮*:

#include<iostream>
#include<stdio.h>
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y){
    if(b==0){
        x=1,y=0;
        return a;
    }
    long long q=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return q;
}
int main(){
    long long a1,c1,a2,c2,x,y,t;
    long long n;
    while(cin>>n){
cout<<"  n="<<n<<endl;
        long long flag=1;
cout<<"  flag="<<flag<<endl;
        cin>>a1>>c1;
cout<<"  a1="<<a1<<"  c1="<<c1<<endl;
        for(long long i=1;i<n;i++){
cout<<"~~ i="<<i<<"  i<"<<n<<" ~~"<<endl;
            cin>>a2>>c2;
cout<<"  a2="<<a2<<"  c2="<<c2<<endl;
cout<<"  exgcd("<<a1<<","<<a2<<","<<x<<","<<y<<")"<<endl;
            long long q=exgcd(a1,a2,x,y);
cout<<"  q="<<q<<"=exgcd()"<<endl;
cout<<"  (c2-c1)%"<<q<<"="<<(c2-c1)%q<<endl;
            if((c2-c1)%q!=0){
                flag=0;
            }
            t=a2/q;
cout<<"  t="<<a2<<"/"<<q<<"="<<t<<endl;
cout<<"  x=(("<<x<<"*("<<c2<<"-"<<c1<<")/"<<q<<")%"<<t<<"+"<<t<<")%"<<t<<"="<<((x*(c2-c1)/q)%t+t)%t<<endl;
            x=((x*(c2-c1)/q)%t+t)%t;
cout<<"  c1="<<c1<<"+"<<a1<<"*"<<x<<"="<<c1+a1*x<<endl;
            c1=c1+a1*x;
cout<<"  a1="<<a1<<"*("<<a2<<"/"<<q<<")="<<a1*(a2/q)<<endl;
            a1=a1*(a2/q);
        }
        if(flag==0){
            cout<<"-1"<<endl;
            continue;
        }
        cout<<c1<<endl;
    }
    return 0;
}

输出结果如下:

 

 虽然不不明白那些式子是怎么推出来的,但是可以看明白其代表的意思:

先取出前两组,让c1保存前两组的解,a1保存余数为c1的除数,将前两组看成一个整体,再与第三组求解,这样

c1保存前三组的解,a1保存余数为的除数,前三组看做一个整体,,,如果有条件不满足,即不满足欧几里得游街的充分必要条件时,flag变为0,无解,否则到最后一步,c1保存的即是全部同余式的解。

果然,我和最笨的方法最搭,先搞懂大致思路,要不然模板我都不知道怎么套,细想了一下我的处境,一身冷汗,我来到这里,不是挣扎反思错误,与懒惰的自己做斗争的,我只有这一次机会,我来不及了,你怎么能现在才明白!!

猜你喜欢

转载自blog.csdn.net/sodacoco/article/details/81540075
今日推荐