AcWing 204. 表达整数的奇怪方式

给定 2n 个整数 a1,a2,…,an 和 m1,m2,…,mn,求一个最小的非负整数 x,满足 ∀i∈[1,n],x≡mi(mod ai)。

输入格式
第 1 行包含整数 n。

第 2…n+1 行:每 i+1 行包含两个整数 ai 和 mi,数之间用空格隔开。

输出格式
输出最小非负整数 x,如果 x 不存在,则输出 −1。
如果存在 x,则数据保证 x 一定在 64 位整数范围内。

数据范围
1≤ai≤2^31−1,
0≤mi<ai
1≤n≤25
输入样例:
2
8 7
11 9
输出样例:
31

中国剩余定理的扩展

#include<bits/stdc++.h>
using namespace std;

typedef long long LL; 

LL exgcd(LL a,LL b,LL &x,LL &y){
    if(b==0){
        x=1,y=0;
        return a;
    }
    else{
        LL d=exgcd(b,a%b,y,x);
        y-=a/b*x;
        return d;
    }
}

int main(){
    int n;
    bool has_answer=true;
    LL a1,m1,a2,m2;
    LL k1,k2;
    cin>>n;
    cin>>a1>>m1;
    for(LL i=1;i<n;i++){
        cin>>a2>>m2;
        LL d=exgcd(a1,a2,k1,k2);
        //cout<<d<<endl;
        if((m2-m1)%d!=0){
            has_answer=false;
            break;
        }
        k1=((m2-m1)/d)*k1;
        LL r=a2/d;
        k1=(k1%r+r)%r;//剔除k1中能被r整除的部分,让k1尽可能小(也就是新的m1尽可能小),否则溢出
        m1=a1*k1+m1;
        a1=a1/d*a2;
    }
    if(!has_answer) cout<<-1;
    else cout<<(m1%a1+a1)%a1;
    return 0;
}
posted @ 2022-05-03 22:05  xhy666  阅读(35)  评论(0)    收藏  举报