一元线性同余方程组


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



一元线性同余方程


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

     $ax\equiv b\,(mod\, m)$

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

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

$ax_0+my_0=d=ax+my\Rightarrow 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\n";
         else cout << ans << endl;
     }
     return 0;
 }

一元线性同余方程组


求解
对于含有两个方程的方程组
$\{\begin{array}{c}
     x\equiv b_1( mod\,m) \\
     x\equiv b_2( mod\,m) \\
\end{array}$
每个方程写成二元不定方程的形式
$\{\begin{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\n");
         else printf("%I64d\n", r0);
     }
     return 0;
 }



多元线性同余方程


定义:
形如$a_1x_1+a_2x_2+a_3x_3+\cdot\cdot\cdot+a_nx_n+b\equiv 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+b\equiv0(mod \, d_1)$
这样把方程拆成了两部分:
1.$a_1x_1+a_2x_2+a_3x_3+\cdot\cdot\cdot+a_nx_n+b\equiv 0(mod\,m)$
2.$a_nx_n+b\equiv0(mod\, d_1)$
当且仅当1,2都成立的时候方程成立。

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

转载于:https://www.cnblogs.com/cniwoq/p/7264720.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值