数论 · 扩展中国剩余定理(EXCRT)
问题
已知有:
在
求解
假设我们已经求解出了前
此时易知前
现在我们要求解一个
转换一下就是
exgcd无处不在!!
假设我们现在用扩欧几里得求解方程
那么
然后我们解得
转化一下:
这样我们就有一个解
详情请戳 ->《数论 · 求解线性同余方程》
设
然后再把它统计到
别忘了也统计到
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
#define rint register int
#define fo(i, a, b) for(rint i (a); i <= b; ++i)
const int maxn = 1e5 + 5;
int n, a[maxn], m[maxn];
int x, y;
inline int read ()
{
int x = 1, s = 0;
char ch = getchar ();
while (ch < '0' or ch > '9') {if (ch == '-') x = -1; ch = getchar ();}
while (ch >= '0' and ch <= '9') s = s * 10 + ch - '0', ch = getchar ();
return x * s;
}
inline int exgcd (int a, int b)
{
if (!b)
{
x = 1, y = 0;
return a;
}
int res = exgcd (b, a % b);
int tmp = x;
x = y, y = tmp - a / b * y;
return res;
}
inline int pmul (int x, int p, int mod)
{
int res = 0;
while (p >= 1)
{
if (p & 1)
res = (res + x) % mod, p -= 1;
p /= 2, x = (x + x) % mod;
}
return res;
}
int M, ans;
inline int excrt ()
{
M = m[1], ans = a[1];
fo (i, 2, n)
{
int a_ = M, b_ = m[i], c_ = (a[i] - ans % b_ + b_) % b_;
int gcd = exgcd (a_, b_), bg = b_ / gcd;
x = pmul (x, c_ / gcd, bg);
ans = ans + x * M;
M *= bg, ans = (ans % M + M) % M;
}
return ans;
}
signed main ()
{
n = read ();
fo (i, 1, n)
m[i] = read (), a[i] = read ();
printf ("%lld\n", excrt ());
return 0;
}
——