poj2891线性同余方程

解线性同余方程组的迭代法
x=r1(mod a1)
x=r2(mod a2)
 
x=a1*t+r1
x=a2*u+r2
a1*t+a2*u=r2-r1
解u,t
令d=(a1,a2) c=r2-r1
当仅当d|c时有解
用extgcd解得a1*t'+a2*u'=d 中的t'和u'
a1*(t'*c/d) + a2*(u'*c/d) = c
解是t=t'/d*c 和 u=u'/d*c
 
然后把t代入x=a1*t+r1
x=x(mod lcm(a1,a2))
然后再递推解第三个以及后面的方程

poj2891

/*
ID: neverchanje
PROG:
LANG: C++11
*/
#include<vector>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<set>
#include<queue>
#include<map>
#define INF 0Xfffffffff
#define st_size (1<<18)-1
#define maxn
typedef  long long ll;
using namespace std;

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

int n;
ll a1,a2,r1,r2;
ll c,d,x,y,t;

int main(){
//    freopen("a.txt","r",stdin);
//    freopen(".out","w",stdout);
    while(cin>>n){
        cin>>a1>>r1;
        bool flag=1;
        for(int i=1;i<n;i++)
        {
            cin>>a2>>r2;
            //对x=r1(mod a1)    x=r2(mod a2)的联立方程组
            c=r2-r1;
            extgcd(a1,a2,d,x,y);
            if(c%d)    flag=0;//无解,注意无解也不能退出循环

            //得到a1*x+a2*y=c中x的解
            t=a2/d;
            x=((x*(c/d))%t+t)%t;//注意
            r1=a1*x+r1;
            a1=(a1*a2)/d;
        }

        printf("%lld\n",flag?r1:-1);
    }
    return 0;
}

/*
DESCRIPTION:

*/

 

 

posted @ 2014-05-27 15:27  neverchanje  阅读(225)  评论(0编辑  收藏  举报