POJ 2891 线性同余方程组

题意

传送门 POJ 2891

题解

线性同余方方程,可以使用拓展欧几里德算法计算逆元求解。对于线性同余方程组,可以通过方程数次拓展欧几里德算法迭代求解。假设方程形式为 a i × x   =   b i ( m o d   m i ) a_i\times x\ = \ b_i(mod\ m_i) ai×x = bi(mod mi),在题目中为 x   =   r i ( m o d   a i ) x\ = \ r_i(mod\ a_i) x = ri(mod ai)。设已求解的前 i i i 个方程的解为 x   m o d   m x\ mod\ m x mod m,可以写成 x + m × t x+m\times t x+m×t,将其代入下一个需要求解的方程,则有
a i ( x + m × t )   =   b i ( m o d   m i ) a_i(x+m\times t)\ = \ b_i (mod \ m_i) ai(x+m×t) = bi(mod mi)
将其写为一般形式
a i × m × t   =   b i − a i × x ( m o d   m i ) a_i\times m \times t\ = \ b_i-a_i\times x(mod \ m_i) ai×m×t = biai×x(mod mi) 求解方程,将 t t t 代入解,就得到了前 i + 1 i+1 i+1 个方程的解。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef pair<ll, ll> P;

ll gcd(ll a, ll b)
{
    return b == 0 ? a : gcd(b, a % b);
}

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

ll inv(ll a, ll m)
{
    ll x, y;
    extgcd(a, m, x, y);
    return (m + x % m) % m;
}

P linear_congruence(const vec &A, const vec &B, const vec &M)
{
    ll x = 0, m = 1;
    for (int i = 0; i < (int)A.size(); ++i)
    {
        ll a = A[i] * m, b = B[i] - A[i] * x, d = gcd(M[i], a);
        if (b % d != 0)
            return P(-1LL, -1LL);
        ll t = b / d * inv(a / d, M[i] / d) % (M[i] / d);
        x = x + m * t;
        m *= M[i] / d;
    }
    return P((m + x % m) % m, m);
}

int main()
{
    int k;
    while (~scanf("%d", &k))
    {
        vec A(k, 1LL), B(k), M(k);
        for (int i = 0; i < k; ++i)
            scanf("%lld%lld", &M[i], &B[i]);
        P res = linear_congruence(A, B, M);
        printf("%lld\n", res.first);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值