• POJ-2891-Strange Way to Express Integers(线性同余方程组)


    链接:

    https://vjudge.net/problem/POJ-2891

    题意:

    Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is described as following:
    Choose k different positive integers a1, a2, …, ak. For some non-negative m, divide it by every ai (1 ≤ i ≤ k) to find the remainder ri. If a1, a2, …, ak are properly chosen, m can be determined, then the pairs (ai, ri) can be used to express m.

    “It is easy to calculate the pairs from m, ” said Elina. “But how can I find m from the pairs?”

    Since Elina is new to programming, this problem is too difficult for her. Can you help her?

    思路:

    考虑同余方程组:
    (x equiv a_1(mod m_1))
    (x equiv a_2(mod m_2))
    ...
    当求第i个式子时,我们有前i-i个方程的特解(x),通解(x+i*m),(m)为前i-1个方程(m)的lcm。
    考虑第i个式子,(x+t*m equiv a_i (mod m_i)),解除最小的t即可。
    上式可转为(t*m + (-k)*m_i = a_i-x),用扩展欧几里得即可得到最小解。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<math.h>
    
    using namespace std;
    typedef long long LL;
    const int INF = 1e9;
    
    const int MAXN = 1e5+10;
    LL A[MAXN], M[MAXN];
    int n;
    
    LL ExGcd(LL a, LL b, LL &x, LL &y)
    {
        if (b == 0)
        {
            x = 1, y = 0;
            return a;
        }
        LL d = ExGcd(b, a%b, x, y);
        LL tmp = x;
        x = y;
        y = tmp-(a/b)*y;
        return d;
    }
    
    LL ExCRT()
    {
        LL res = A[1], m = M[1];
        for (int i = 2;i <= n;i++)
        {
            LL d, x, y;
            d = ExGcd(m,M[i], x, y);
            if ((A[i]-res)%d)
                return -1;
            x = x*(A[i]-res)/d;
            //cout << x << ' ' << y << ' ' << d << endl;
            x = (x%(M[i]/d)+(M[i]/d))%(M[i]/d);
            res = res+x*m;
            m = (m*M[i])/d;
            res %= m;
        }
        return (res%m+m)%m;
    }
    
    int main()
    {
        while(~scanf("%d", &n))
        {
            for (int i = 1;i <= n;i++)
                scanf("%lld%lld", &M[i], &A[i]);
            printf("%lld
    ", ExCRT());
        }
    
        return 0;
    }
    
  • 相关阅读:
    python3+request接口自动化框架
    类型转换函数
    操作符重载(三)
    操作符重载(二)
    操作符重载(一)
    时间获取函数
    文件和目录
    Linux五种IO模型
    类中的函数重载
    系统调用IO和标准IO
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11789628.html
Copyright © 2020-2023  润新知