中国剩余定理及其拓展
中國剩余定理
實質就是解nnn次互質的方程,然后分別乘以他們的取模剩余量,然后相加得到答案,這里就不展開敘述。
typedef long long ll; const int N = 1e3 + 10; int a[N], b[N], n; void exgcd(ll a, ll b, ll &x, ll &y) {if(!b) {x = 1;y = 0;return ;}exgcd(b, a % b, x, y);ll temp = x;x = y;y = temp - a / b * y;return ; } void solve() {ll m = 1, x, y, ans = 0;for(int i = 1; i <= n; i++)m *= b[i];for(int i = 1; i <= n; i++) {ll t = m / b[i];exgcd(t, b[i], x, y);ans = (ans + x * t * a[i]) % m;}ans = (ans + m) % m;printf("%lld\n", ans); } int main() {scanf("%d", &n);for(int i = 1; i <= n; i++)scanf("%d %d", &a[i], &b[i]);//a[i]是余數,b[i]是模數。solve();return 0; }中國剩余定理拓展
思路
我們規定b[i]b[i]b[i]時余數,a[i]a[i]a[i]是模數。
顯然對于一個方程我們可以直接得到ans1=b[1]ans_1 = b[1]ans1?=b[1],用這個答案去求解第二個方程,解顯然可以描述為ans2=ans1+k?a[1]ans_2 = ans_1 + k * a[1]ans2?=ans1?+k?a[1],所以第二個方程的解可以如下推理:
ans1+k?a[1]≡b[2](moda[2])ans1 + k * a[1] \equiv b[2] \pmod {a[2]}ans1+k?a[1]≡b[2](moda[2])
k?a[1]≡b[2]?ans1(moda[2])k * a[1] \equiv {b[2] - ans1} \pmod{a[2]}k?a[1]≡b[2]?ans1(moda[2])
所以我們只要解的kkk就行,無非就是做一次exgcdexgcdexgcd嘛,得到
ans2=ans1+k?a[1]ans_2 = ans_1 + k * a[1]ans2?=ans1?+k?a[1]
如果繼續拓展下去,我們顯然有ansk=i=1i=k?1lcm?k+ansk?1ans_k = _{i = 1} ^ {i = k - 1} lcm * k + ans_{k - 1}ansk?=i=1i=k?1?lcm?k+ansk?1?,也就是把上面推導的式子換成前k?1k - 1k?1項的lcmlcmlcm。
P4777 【模板】擴展中國剩余定理(EXCRT)
裸題。
/*Author : lifehappy */ // #pragma GCC optimize(2) // #pragma GCC optimize(3) // #include <bits/stdc++.h>#include <cstdio> #include <iostream> #include <stdlib.h> #include <algorithm> #include <cmath>#define mp make_pair #define pb push_back #define endl '\n'using namespace std;typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii;const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x; }void print(ll x) {if(x < 10) {putchar(x + 48);return ;}print(x / 10);putchar(x % 10 + 48); }const int N = 1e5 + 10;ll a[N], b[N]; int n;ll quick_mult(ll a, ll b, ll mod) {ll ans = 0;while(b) {if(b & 1) ans = (ans + a) % mod;b >>= 1;a = (a + a) % mod;}return ans; }ll ex_gcd(ll a, ll b, ll & x, ll & y) {if(!b) {x = 1, y = 0;return a;}ll gcd = ex_gcd(b, a % b, x, y);ll temp = x;x = y;y = temp - a / b * y;return gcd; }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read();for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();ll ans = b[1], M = a[1];for(int i = 2; i <= n; i++) {ll A = M, B = a[i], C = ((b[i] - ans) % a[i] + a[i]) % a[i], x, y;ll gcd = ex_gcd(A, B, x, y);B /= gcd;x = quick_mult(x, C / gcd, B);ll mod = M * B;ans = (ans + quick_mult(x, M, mod)) % mod;M = mod;}printf("%lld\n", ((ans % M) + M) % M);return 0; }總結
以上是生活随笔為你收集整理的中国剩余定理及其拓展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bp神经网络和神经网络,bp神经网络的应
- 下一篇: QT QDir 基本函数使用