• 一元线性同余方程组



    设整系数多项式
    $f(x)=a_nx^n+a_{n-1}x^{n-1}+cdotcdotcdot+a_1x+a_0$
    我们讨论的是是否有正数值$x$满足同余式
    $f(x)equiv 0(mod\,m)$
    这个方程式称为模m的同于方程式
    如果$c$满足$f(c)equiv 0(mod\,m)$则称$c$为同余方程的解。
    记作$xequiv c(mod\, m)$
    这实际上是把同余类$c\,mod\,m$看作是满足方程的一个解。当$c_1$,$c_2$均为同余方程的解,并且对模$m$不同余的时候才把他们看做同余方程的不同解。显然,模$m$的同余方程解的个数最多有$m$个。



    一元线性同余方程


    定义:
    $a$,$b$是整数,$m$是正整数,形如

         $axequiv b\,(mod\, m)$

    且$x$是未知数的同余式称作一元线性同余方程。

    求解:
    对于方程
    $axequiv b\,(mod\, m)$, 可以把它写成二元一次不定式$ax+my=b$。要想方程有解,必须满足$(a,m)mid d$。 这时利用扩展欧几里得求出$ax+my=(a,m)$的一个特解,在乘上$b/(a,m)$就是我们所要的一个特解。
    利用公式:

    $ax_0+my_0=d=ax+myRightarrow a(x-x_0)+m(y-y_0)=0$、

    $(frac{a}{(a,m)}, frac{m}{(a,m)}) = 1 $

    $x = x_0-frac{m}{(a,m)}t$

    这样就得到了$x$的所有解,其中最小的整数解是
    $ (x\,mod\,frac{m}{(a,m)}+frac{m}{(a,m)} ) \,mod\,frac{m}{(a,m)} $

    POJ 2115就是求当$a=C$,$b=B-A$,$m=2^k$的最小解

    #include "iostream"
     using namespace std;
    typedef long long LL;
    void ext_gcd(LL a, LL b, LL &s, LL& x, LL& y) {
         LL res;
         if (!b){x = 1; y = 0; s = a;}
         else {
             ext_gcd(b, a%b, s, y, x);
             y -= x*(a/b);
         }
     }
     LL mod_line(LL a, LL b, LL m) {
         LL x, y, d;ext_gcd(a, m, d, x, y);
         if (b%d) return -1;
         LL e = x*(b/d)%(m/d) + (m/d);
         return e%(m/d);
     }
    int main(int argc, char const *argv[])
     {
         LL a,b,c,d;
         while (cin >> a >> b >> c >> d) {
             if (!a&&!b&&!c&&!d) break;
             LL ans = mod_line(c, b-a, (LL)1 << d);
             if (ans == -1) cout << "FOREVER
    ";
             else cout << ans << endl;
         }
         return 0;
     }

    一元线性同余方程组


    求解
    对于含有两个方程的方程组
    ${egin{array}{c}
         xequiv b_1( mod\,m) \
         xequiv b_2( mod\,m) \
    end{array}$
    每个方程写成二元不定方程的形式
    ${egin{array}{c}
         x=b_1+m_1y_1 \
         x=b_2+m_2y_2 \
    end{array}$
    所以得到方程$m_2y_2-m_1y_1=b_1-b_2$,在对$y_2$进行求解。
    因此得到小于$m$的非负正整数解为$(b_2+m_2y_2)mod\, [m_1,m_2]$
    如果方程组有两个以上的话,进行两两合并求解。
    POJ 2891裸的同余方程组

    #include "iostream"
     #include "stdio.h"
     using namespace std;
     typedef long long LL;
     void ext_gcd(LL a, LL b, LL &d, LL& x, LL& y) {
         LL res;
         if (!b){x = 1; y = 0; d = a;}
         else {
             ext_gcd(b, a%b, d, y, x);
             y -= x*(a/b);
         }
     }
     LL mod_line(LL a, LL b, LL m, LL& d) {
         LL x, y; ext_gcd(a, m, d, x, y);
         if (b%d) return -1;
         LL e = x*(b/d)%(m/d) + (m/d);
         return e%(m/d);
     }
     int main(int argc, char const *argv[])
     {
         int n;
         while (scanf("%d", &n) != EOF) {
             bool flag = false;
             LL r0, r1, m0, m1;
             scanf("%I64d%I64d", &m0, &r0);  //x=r mod m
             for (int i = 1; i < n; i++) {
                 LL d;
                 scanf("%I64d%I64d", &m1, &r1);
                 LL x0 = mod_line(m0,r1 - r0, m1, d);
                 if (flag || x0 == -1) {flag = true;  continue;}
                 r0 = x0*m0+r0;
                 m0 = m0*(m1/d);
                 r0 %= m0;
             } 
             if (flag) printf("-1
    ");
             else printf("%I64d
    ", r0);
         }
         return 0;
     }



    多元线性同余方程


    定义:
    形如$a_1x_1+a_2x_2+a_3x_3+cdotcdotcdot+a_nx_n+bequiv 0(mod\,m)$的同余方程称为多元线性同余方程。
    性质:
    多元线性同余方程有解的充要条件是:$(a_1,a_2,a_3,cdots,a_n,m)mid b$。若方程有解,则解的个数为$m^{n-1}(a_1,a_2,a_3,cdots,a_n,m)$。
    求解:
    令$d=(a_1,a_2,a_3,cdots,a_n,m),d_1=(a_1,a_2,a_3,cdots,a_{n-1},m)$那么$(d_1,a_n)=d$,所以$a_nx_n+bequiv0(mod \, d_1)$
    这样把方程拆成了两部分:
    1.$a_1x_1+a_2x_2+a_3x_3+cdotcdotcdot+a_nx_n+bequiv 0(mod\,m)$
    2.$a_nx_n+bequiv0(mod\, d_1)$
    当且仅当1,2都成立的时候方程成立。

    ####参考了哈工大系列的书,做了个总结

  • 相关阅读:
    HackerRank
    HackerRank
    HackerRank
    LeetCode "Bitwise AND of Numbers Range"
    HackerRank
    HackerRank
    LeetCode "Binary Tree Right Side View"
    HihoCoder
    HihoCoder
    HackerRank
  • 原文地址:https://www.cnblogs.com/cniwoq/p/7264720.html
Copyright © 2020-2023  润新知