zoukankan      html  css  js  c++  java
  • 数论-扩展中国剩余定理

    求解 n 个同余方程

    x ≡ Ci (mod Mi)

    推荐一下讲证明的文章:

    1.https://www.cnblogs.com/TheRoadToTheGold/p/8458326.html 很简洁易懂。

    2.http://blog.csdn.net/clove_unique/article/details/54571216 排版不太好;这篇文章还讲了扩展卢卡斯 (Lucas) 定理。

     可以用滚动数组优化空间,但我的代码里没这么写。

     1 void China()
     2 {
     3     scanf("%lld", &n);
     4     for (i = 1; i <= n; ++i)
     5         scanf("%lld%lld", &M[i], &C[i]);
     6     bool flag = false;
     7     for (i = 2; i <= n; ++i) {
     8         LL m1 = M[i-1], m2 = M[i], c1 = C[i-1], c2 = C[i];
     9         LL t = gcd(m1, m2);
    10         if ((c2-c1) % t) { flag = true; break; }
    11         M[i] = m1*m2 / t;
    12         C[i] = Inv(m1/t, m2/t) * (c2-c1)/t % (m2/t) * m1 + c1;
    13         C[i] = (C[i]%M[i]+M[i]) % M[i];
    14     }
    15     if (flag) { printf("-1
    "); continue; }
    16     printf("%lld
    ", C[n]);
    17 }

    模板题 POJ2891

     1 #include <stdio.h>
     2 
     3 typedef long long LL;
     4 
     5 const int _N = 1200;
     6 
     7 LL C[_N], M[_N];
     8 
     9 void exgcd(LL m, LL n, LL &x, LL &y, LL &d)
    10 {
    11     if (n) { exgcd(n, m%n, y, x, d); y -= m/n*x; return; }
    12     x = 1, y = 0, d = 1;
    13     return;
    14 }
    15 
    16 LL gcd(LL t1, LL t2) { return t2 ? gcd(t2, t1 % t2) : t1; }
    17 
    18 LL Inv(LL v, LL p)
    19 {
    20     LL x, y, d;
    21     exgcd(v, p, x, y, d);
    22     x = (x%p+p)%p;
    23     if (!x) x = p;
    24     return x;
    25 }
    26 
    27 int main()
    28 {
    29     LL n, i;
    30     while (~scanf("%lld", &n)) {
    31         for (i = 1; i <= n; ++i)
    32             scanf("%lld%lld", &M[i], &C[i]);
    33         bool flag = false;
    34         for (i = 2; i <= n; ++i) {
    35             LL m1 = M[i-1], m2 = M[i], c1 = C[i-1], c2 = C[i];
    36             LL t = gcd(m1, m2);
    37             if ((c2-c1) % t) { flag = true; break; }
    38             M[i] = m1*m2 / t;
    39             C[i] = Inv(m1/t, m2/t) * (c2-c1)/t % (m2/t) * m1 + c1;
    40             C[i] = (C[i]%M[i]+M[i]) % M[i];
    41         }
    42         if (flag) { printf("-1
    "); continue; }
    43         printf("%lld
    ", C[n]);
    44     }
    45     return 0;
    46 }
  • 相关阅读:
    toString和equals两个比较常见的重写方式
    Java内构造函数、关键字、权限修饰符、访问控制及面向对象的特性!
    java中一个重要思想:面向对象
    JAVA基础汇总及例题详解
    java数据类型转换和数组总结
    java的数据基础
    HTML中的表格、表单元素与框架的构建
    linux命令学习(持续更新......)
    javascript bind在回调中精简匿名函数的用法
    CSS 文字超长省略显示并隐藏超长部分
  • 原文地址:https://www.cnblogs.com/ghcred/p/8458538.html
Copyright © 2011-2022 走看看