poj2891--扩展欧几里德算法

本文介绍如何利用扩展欧几里德算法解决模线性同余方程的问题,详细阐述了方程的合并过程及通解的推导。
/*
该题使用的是扩展欧几里德算法,求模线性同余方程;
分析题目:以题目输出结果为例 ,要求得到一个整数X可以满足 X % a = r,a,r,为数组名;
设数组元素为两个时, 
列出方程:X % a1 = r1;
          X % a2 = r2;
可得出:  a1*k1 + r1 = X;
          a2*k2 + r2 = X;
合并方程:a1*k1 + r1 = a2*k2 + r2,经变形得
          a1*k1 - a2*k2 = r2 - r1;
由扩展欧几里德算法公式:ax + by = c;
得到 k1, 再将 k1 反代入 a1*k1 + r1 = X 中得到 X ,
于是X就是这两个方程的一个特解,通解就是 X'=X+k*LCM(m1,m2)
这个式子再一变形,得 X' mod LCM(m1,m2)=X
这个方程一出来,说明我们实现了(1)(2)两个方程的合并。
令 M=LCM(m1,m2),R=r2-r1
就可将合并后的方程记为 X mod M = R。 
*/
#include<iostream>
#define LL long long
using namespace std;
void gcd(LL a,LL b,LL &d,LL &x,LL &y){
    if(!b){
        d=a;x=1;y=0;
    }
    else{
        gcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
LL get(LL *a,LL *r,int n){
    LL A=a[0],R=r[0],d,x,y,sum,T;
    for(int i=1;i<n;i++){
        gcd(A,a[i],d,x,y);
        if((r[i]-R)%d!=0)
        return -1;
        x=x*(r[i]-R)/d;
        T=a[i]/d;
        x=x%T;//得到x的最小整数解 
        R=A*x+R;//将x代入回原方程 
        A=A*a[i]/d;//求最小公倍数 
        R=R%A;
    }
    return R>0?R:R+A;
}
int main(){
    int n;
    while(cin>>n){
        LL a[100000],r[100000];
        for(int i=0;i<n;i++){
            cin>>a[i]>>r[i];
        }
        cout<<get(a,r,n)<<endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/tz346125264/p/4869113.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值