您的位置:首页 > 新闻 > 资讯 > 拓展中国剩余定理

拓展中国剩余定理

2025/2/25 9:54:29 来源:https://blog.csdn.net/qq_73631501/article/details/140280650  浏览:    关键词:拓展中国剩余定理

题目链接

代码:

/*扩展中国剩余定理的使用范围更广泛,不要求模数全部互质扩展中国剩余定理:两两合并同余方程,合并 n - 1 次之后,就能求解合并两个同余方程:x ≡ r1 (mod p1) --- x = a*p1 + r1x ≡ r2 (mod p2) --- x = b*p2 + r2由上面两式得:x = a*p1 + r1 = b*p2 + r2 --- a*p1 - b*p2 = r2 - r1根据裴蜀定理,算式 a*p1 - b*p2 = r2 - r1:当 gcd(p1, p2) | (r2 - r1) 时,有解通过扩展欧几里得算法可得特解为:A = X / gcd(p1, p2) * (r2 - r1) B = Y / gcd(p1, p2) * (r2 - r1)
那么通解就是:AA = A + p2/gcd(p1, p2) * kBB = B - p1/gcd(p1, p2) * k将解代入原方程:x = AA * p1 + r1 = p1*p2/gcd(p1, p2) * k + p1*A + r1
又变成了 x = a * p + r 的形式这样合并 n - 1 次,就能得出结果*/#include <iostream>using namespace std;typedef __int128 LL;const int N = 1e5 + 10;int n;
LL p[N], r[N];inline LL read()
{LL x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}inline void print(LL x)
{if(x < 0){putchar('-');x = -x;}if(x > 9) print(x / 10);putchar(x % 10 + '0');
}LL exgcd(LL a, LL b, LL& x, LL& y)
{if(b == 0){x = 1, y = 0;return a;}LL x1, y1, d;d = exgcd(b, a % b, x1, y1);x = y1, y = x1 - a / b * y1;return d;
}LL excrt()
{LL p1 = p[1], r1 = r[1];for(int i = 2; i <= n; i++){LL p2 = p[i], r2 = r[i];// 二元一次不定方程:p1 * x + p2 * y = r2 - r1LL x, y, d, c = r2 - r1;d = exgcd(p1, p2, x, y);if(c % d) return -1;x = c / d * x, y = c / d * y; // 求出特解// x 有可能是负数,补正一下LL mod = p2 / d;x = (x % mod + mod) % mod;// 求出合并后的 p 和 r,一定要先更新 r,因为会用到 p 的值r1 = x * p1 + r1;p1 = p1 / d * p2;}return r1 % p1;
}int main()
{scanf("%d", &n);for(int i = 1; i <= n; i++) p[i] = read(), r[i] = read();print(excrt());return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com