HihoCoder - 1303 数论六·模线性方程组

裸的一个模线性方程组,重在理解一下这个求的过程。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<set>
#include<algorithm>
#include<vector>
#include<queue>
#include<list>
#include<cmath>
#include<cstring>
#include<map>
#include<stack>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 1005
#define ull unsigned long long
#define ll long long
#define hashmod 99999839
#define mod 9997
int n;
ll m[maxn],r[maxn];
ll gcd(ll a,ll b){
    return (b==0)?a:gcd(b,a%b);
}
ll exgcd(ll a,ll b,ll& x,ll& y){
    if(!b){x = 1,y = 0;return a;}
    ll g = exgcd(b,a%b,x,y);
    ll t = x;
    x = y;
    y = t - a/b * x;
    return g;
}
void solve(){
    bool f = true;
    ll x,y,z;
    for(int i = 2;i <= n;++i){
        ll g = gcd(m[i-1],m[i]);
        if((r[i]-r[i-1])%g!=0){
            f = false;
            break;
        }
        z=(r[i]-r[i-1])/g;
        exgcd(m[i-1]/g,m[i]/g,x,y);//AX+BY=1的(X,Y)
        x *= z;//y *= z,AX + BY = C
        x = x + (abs(x) / (m[i]/g) + 1) * (m[i]/g);//将X扩展为非负数,X = x + B/(A,B) = (x + K*B/(A,B)) % (B/(A,B))
        x = x % (m[i]/g);//防止溢出
        z = x * m[i-1]+r[i-1];//得到两个方程式的特解
        m[i] = m[i]/g*m[i-1];//得到lcm(A,B)
        r[i] = z % m[i];
    }
    if(f) printf("%lld\n",r[n]);
    else printf("%lld\n",-1ll);
}
int main(){
    freopen("a.in","r",stdin);
    freopen("b.out","w",stdout);
    while(~scanf("%d",&n)){
        for(int i = 1;i <= n;++i){
            scanf("%d%d",&m[i],&r[i]);
        }
        solve();
    }
    return 0;
}

 

posted @ 2018-08-22 11:37  zhuiyicc  阅读(112)  评论(0编辑  收藏  举报