洛谷P4777 【模板】扩展中国剩余定理(EXCRT)
题外话:这次同步赛Day2 P1考到了exCRT,去网上拉了个错误的板子一个小时都没调出来。
所以。。。我来刷了一道板子题。
题意
给定线性模方程组
$$\begin{cases} x \equiv b_1\ ({\rm mod}\ a_1) \\ x\equiv b_2\ ({\rm mod}\ a_2) \\ ... \\ x \equiv b_n\ ({\rm mod}\ a_n)\end{cases}$$
求$x$的最小正整数解
题解
一道板子好题。
直接上代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n; ll a[100055], b[100055];
/***************** BAN ZI START ******************/
ll readint() {
ll ret; scanf(LL, &ret); return ret;
}
inline ll MulMod(ll a, ll b, ll m){
ll t = a * b - (ll)((long double)a * b / m + 1e-10) * m;
return (t %= m) < 0 ? t + m : t;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1,y=0;return a;
}
ll ret=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return ret;
}
ll excrt(ll*r,ll*a,int n){
ll M=a[1],R=r[1],x,y,d;
for(int i=2;i<=n;i++){
d=exgcd(M,a[i],x,y);
x=MulMod((R-r[i])/d, x, a[i]);
R -= M*x;
M = M/d * a[i];
}
return (R%M+M)%M;
}
/***************** BAN ZI END ******************/
int main() {
n = readint();
for (int i=1; i<=n; i++) b[i] = readint(), a[i] = readint();
ll ans = excrt(a, b, n);
printf("%lld\n", ans);
return 0;
}

浙公网安备 33010602011771号