原地址:http://hi.baidu.com/aekdycoin/blog/item/71d7a842b93f611b73f05da4.html
给定方程
x = c1 (mod b1) ……………………(1)
x = c2(mod b2) ………………………(2)
(b1,b2)可以不为1
于是通过取mod 定义,我们得到
x = k1 * b1 + c1………………(3)
(3) 带入(2)
k1 * b1 + c1 = c2 (mod b2)…………(4)
化简
k1 * b1 = c2 - c1 (mod b2)…………(5)
于是可以解得到
令G = gcd(b1,b2),C = c2 - c1 (mod b2)
那么由(5)得到
k1 * b1 = W * b2 + C
---->>>>>
k1 * b1 / G = W * b2 / G + C / G
令C' = C/G
k1 * b1 / G = W * b2 / G + C '
k1 * b1 / G = C' (mod b2 / G)
--->
{
关于(6)怎么得到的,我做一下解释。在这纠结了好长时间。
(k1*(b1/G)) % (b2/G) = C' %(b2/G);
k1%(b2/G) = C'%(b2/G) / (b1/G)%(b2/G);
k1%(b2/G) = (C' * Xb1) % (b2/G) ; Xb1是b1的逆元
令K = C' * Xb1;
}
k1 = K (mod b2/G)………………(6)
那么有
k1 = k' * b2/G + K………………(7)
(7)带入(3)
x = k' * b2 * b1/G + K * b1 + c1………………(8)
x = K*b1 + c1 (mod b1 * b2/G)
证毕!
贴一下模板 POJ 2891 很典型的这种问题:
//合并到最后得到一个式子 x = c(mod b);所以要求的x就是c。 #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) typedef long long LL; using namespace std; LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; } LL ext_gcd(LL a, LL b, LL& x, LL& y) { if(b == 0) { x = 1; y = 0; return a; } LL p = ext_gcd(b, a%b, x, y); LL tmp = x; x = y; y = tmp - (a/b)*y; return p; } LL inmod(LL a, LL n) { LL x, y; if(ext_gcd(a, n, x, y) != 1) return -1; return (x%n + n)%n; } int mergef(LL b1, LL c1, LL b2, LL c2, LL& b, LL& c) { LL tb1 = b1, tb2 = b2; c = ((c2 - c1)%b2 + b2)%b2; LL G = gcd(b1, b2); if(c%G) return 0; c /= G; b1 /= G; b2 /= G; c *= inmod(b1, b2); c %= b2; c *= tb1; c += c1; b = tb1*tb2/G; c %= b; return 1; } int main() { //freopen("data.in", "r", stdin); int t, i; LL b1, c1, b2, c2, b, c; while(~scanf("%d", &t)) { bool flag = true; scanf("%lld%lld", &b1, &c1); if(c1 >= b1) flag = false; for(i = 1; i < t; ++i) { scanf("%lld%lld", &b2, &c2); if(c2 >= b2) flag = false; if(!flag) continue; if(mergef(b1, c1, b2, c2, b, c) == 0) flag = false; //printf("(%d %d), (%d %d), (%d %d)\n", b1, c1, b2, c2, b, c); b1 = b; c1 = c; } if(flag) printf("%lld\n", c); else printf("-1\n"); } return 0; }