[关闭]
@wsndy-xx 2018-06-16T09:03:53.000000Z 字数 774 阅读 889

Poj 2891

题解


中国剩余定理扩展模板题

  1. /*
  2. x = m1 * x1 + a1 = m2 * x2 + a2
  3. => m1 * x1 + a1 = m2 * x2 + a2
  4. => m1 * x1 + m2 * x2 = a2 - a1
  5. gcd(m1, m2) | a2 - a1
  6. x0 为方程
  7. m1 * x1 + m2 * x2 = gcd(m1, m2) 的特解
  8. x0 *= [(a2 - a1) / gcd(m1, m2)]
  9. x0 为方程
  10. m1 * x1 + m2 * x2 = a2 - a1 的一组解
  11. x0 + m2 / gcd * t 化为最小
  12. 将 x0 回带 x' = a1 + m1 * x1
  13. 显然 x 的通解为 x' + lcm(m1, m2)t, 才能保证 x % m1, m2 的余数分别为 a1, a2.
  14. 相当于 x = x' (mod lcm(m1, m2))
  15. 然后与第三个方程继续进行合并
  16. */
  17. #include <iostream>
  18. #include <cstdio>
  19. const int N = 1e5 + 10;
  20. #define LL long long
  21. LL m[N], a[N], n;
  22. LL Exgcd(LL a, LL b, LL &x, LL &y) {
  23. if(!b) {x = 1, y = 0; return a;}
  24. int ret = Exgcd(b, a % b, x, y);
  25. int tmp = x; x = y, y = tmp - a / b * y;
  26. return ret;
  27. }
  28. inline LL Work() {
  29. LL M = m[1], A = a[1], x, y;
  30. for(int i = 2; i <= n; i ++) {
  31. LL d = Exgcd(M, m[i], x, y);
  32. if((a[i] - A) % d) return -1;
  33. x *= ((a[i] - A) / d);
  34. LL t = m[i] / d;
  35. x = ((x % t) + t) % t;
  36. A = A + M * x; M = M / d * m[i];
  37. A %= M;
  38. }
  39. A = (A % M + M) % M;
  40. return A;
  41. }
  42. int main() {
  43. while(std:: cin >> n) {
  44. for(int i = 1; i <= n; i ++) std:: cin >> m[i] >> a[i];
  45. std:: cout << Work() << "\n";
  46. }
  47. return 0;
  48. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注