zoukankan      html  css  js  c++  java
  • 【洛谷P4777】扩展中国剩余定理(Excrt)

    Description

    给定若干个形如$xequiv a_i pmod {b_i}$的同余方程,其中b不保证两两互质,求最小非负整数解x

    Solution

    扩展中国剩余定理的模板题。

    假定我们已经求出了前k-1个方程的一个解为x

    并且记$M=prodlimits_{i=1}^{k-1}{b_i}$

    那么前k-1个方程的通解为$x+iM$

    考虑当前第k个方程,我们要求出一个t,使得$x+tMequiv a_k pmod {b_k}$

    变形,得$tM+Nb_k=a_k-x$

    这个式子可以用Exgcd求解,若Exgcd有解,那么满足前k个方程的一个解为$x_k=x+tM$

    所以我们求解n次扩展欧几里得算法即可得到解,时间复杂度为$O(nlogn)$

    Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 inline ll read() {
     5     ll ret = 0, op = 1;
     6     char c = getchar();
     7     while (!isdigit(c)) {
     8         if (c == '-') op = -1; 
     9         c = getchar();
    10     }
    11     while (isdigit(c)) {
    12         ret = ret * 10 + c - '0';
    13         c = getchar();
    14     }
    15     return ret * op;
    16 }
    17 ll mul(ll a, ll b, ll mod) {
    18     ll ret = 0;
    19     while (b) {
    20         if (b & 1) ret = ret + a % mod;
    21         a = a + a % mod;
    22         b >>= 1;
    23     }
    24     return ret;
    25 }
    26 ll exgcd(ll a, ll b, ll &x, ll &y) {
    27     if (!b) {
    28         x = 1, y = 0;
    29         return a;
    30     }
    31     ll gcd = exgcd(b, a % b, x, y);
    32     ll x2 = x, y2 = y;
    33     x = y2; 
    34     y = x2 - (a / b) * y2;
    35     return gcd;
    36 }
    37 ll ans, a[100010], b[100010], n, M;
    38 inline ll excrt() {
    39     ans = a[1]; M = b[1];
    40     for (register int i = 2; i <= n; ++i) {
    41         ll x, y, A = M, B = b[i], C = (a[i] - ans % b[i] + b[i]) % b[i];
    42         ll gcd = exgcd(A, B, x, y);
    43         x = mul(x, C / gcd, B / gcd);
    44         ans += x * M;
    45         M *= B / gcd;
    46         ans = (ans % M + M) % M;
    47     }
    48     return (ans % M + M) % M;
    49 }
    50 int main() {
    51     n = read();
    52     for (register int i = 1; i <= n; ++i) {
    53         b[i] = read(), a[i] = read();
    54     }
    55     printf("%lld
    ", excrt());
    56     return 0;
    57 }
    AC Code
  • 相关阅读:
    如何让你的Sublime和Codeblocks支持C++11
    Python print不换行输出的替代方法
    阶梯博弈
    hdu4633_Polya定理
    Ural_1169_Pairs
    ACM竞赛中的魔方问题专题(不定时更新)
    LintCode 35. 翻转链表
    windows中mysql5.7中配置中文字符集和默认datadir
    CentOS7使用打开关闭防火墙与端口
    关于阿里巴巴开发手册"不得使用外键与级联,一切外键概念必须在应用层解决"的疑惑
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11291448.html
Copyright © 2011-2022 走看看