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;

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

你可能感兴趣的:(poj)