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;

這么一來~~大功告成~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM