zoukankan      html  css  js  c++  java
  • poj 2891(一般模线性方程组)

    //不满足除数两两互质。

     1 // File Name: 2891.cpp
     2 // Author: Missa_Chen
     3 // Created Time: 2013年06月01日 星期六 15时23分19秒
     4 
     5 #include<iostream>
     6 #include<string>
     7 #include<algorithm>
     8 #include<cstdio>
     9 #include<cstring>
    10 #include<cmath>
    11 #include<queue>
    12 #include<map>
    13 #include<stack>
    14 #include<set>
    15 #include<cstdlib>
    16 
    17 using namespace std;
    18 
    19 #define LL long long
    20 const int inf = 0x3f3f3f3f;
    21 const int maxn = 1e5 + 5;
    22 int n;
    23 void ex_gcd(LL a, LL b, LL &d, LL &x, LL &y)
    24 {
    25     if (!b) {d = a, x = 1, y = 0;}
    26     else
    27     {
    28         ex_gcd(b, a % b, d, y, x);
    29         y -= x * (a / b);
    30     }
    31 }
    32 LL ex_crt(LL *m, LL *r, int n)
    33 {
    34     LL M = m[1], R = r[1], x, y, d;
    35     for (int i = 2; i <= n; ++i)
    36     {
    37         ex_gcd(M, m[i], d, x, y);
    38         if ((r[i] - R) % d) return -1;
    39         x = (r[i] - R) / d * x % (m[i] / d);
    40         R += x * M;
    41         M = M / d * m[i];
    42         R %= M;
    43     }
    44     return R > 0 ? R : R + M;
    45 }
    46 int main()
    47 {
    48     while (~scanf("%d",&n))
    49     {
    50         LL m[maxn], r[maxn];
    51         for (int i = 1; i <= n; ++i)
    52             scanf("%lld%lld", &m[i], & r[i]);
    53         printf("%lld\n",ex_crt(m,r,n));
    54     }
    55     return 0;
    56 }

    转载:

    /**********************一般模线性方程组***********************/

    同样是求这个东西。。
    X mod m1=r1
    X mod m2=r2
    ...
    ...
    ...
    X mod mn=rn

    首先,我们看两个式子的情况
    X mod m1=r1……………………………………………………………(1)
    X mod m2=r2……………………………………………………………(2)
    则有 
    X=m1*k1+r1………………………………………………………………(*)
    X=m2*k2+r2
    那么 m1*k1+r1=m2*k2+r2
    整理,得
    m1*k1-m2*k2=r2-r1
    令(a,b,x,y,m)=(m1,m2,k1,k2,r2-r1),原式变成
    ax+by=m
    熟悉吧?

    此时,因为GCD(a,b)=1不一定成立,GCD(a,b) | m 也就不一定成立。所以应该先判 若 GCD(a,b) | m 不成立,则!!!方程无解!!!。
    否则,继续往下。

    解出(x,y),将k1=x反代回(*),得到X。
    于是X就是这两个方程的一个特解,通解就是 X'=X+k*LCM(m1,m2)
    这个式子再一变形,得 X' mod LCM(m1,m2)=X
    这个方程一出来,说明我们实现了(1)(2)两个方程的合并。
    令 M=LCM(m1,m2),R=r2-r1
    就可将合并后的方程记为 X mod M = R。

    然后,扩展到n个方程。
    用合并后的方程再来和其他的方程按这样的方式进行合并,最后就能只剩下一个方程 X mod M=R,其中 M=LCM(m1,m2,...,mn)。
    那么,X便是原模线性方程组的一个特解,通解为 X'=X+k*M。

    如果,要得到X的最小正整数解,就还是原来那个方法:

    X%=M;
    if (X<0) X+=M;

    这么一来~~大功告成~~

  • 相关阅读:
    03把IL编译成可执行文件
    02值类型
    报错:该字符串未被识别为有效的DateTime
    01使用ILDasm.exe将可执行文件反编译成IL代码
    MVC自定义路由02-实现IRouteConstraint限制控制器名
    MVC自定义路由01-为什么需要自定义路由
    报错:System.Data.Entity.Infrastructure.DbUpdateException 更新条目时出错
    输入网址背后发生的故事
    使用jquery加载部分视图02-使用$.ajax()
    使用jquery加载部分视图01-使用$.get()
  • 原文地址:https://www.cnblogs.com/Missa/p/3112536.html
Copyright © 2011-2022 走看看