Article directory
Question 256. Luogu P1495 Chinese Remainder Theorem - [Template] Chinese Remainder Theorem (CRT)/Cao Chong Pig Raising
1. About the Chinese Remainder Theorem CRT
1 Overview
It is used to solve the system of univariate linear congruence equations (b1, b2, ..., bk are relatively prime in pairs) of the following form: In
layman's terms, it is possible to find a number x, and the remainder of the number to bi is equal to ai, and i ranges from 1 to k.
2. Algorithm steps
Let the divisor be ai and the remainder be bi, i∈[0,N) and i∈Z. The required number is res
① Find the product n of all divisors ai
② Find the multiple m of all divisors except ai, m=n/ai
③ Use the extended Euclidean algorithm or Fermat's little theorem to get the inverse of m mm
④ Multiply m by mm by the remainder bi, and add the result to res. If the total result seems to be very large, perform the modulo operation according to the modulo formula
⑤i++, go back to ②, and end the operation when i=N
Second, the topic
3. Problem solving
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+1;
ll a[maxn],b[maxn];
ll ex_gcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得算法
{
if(b==0)
{
x=1;
y=0;
return a;
}
ll ans=ex_gcd(b,a%b,x,y);
ll tmp=x;
x=y;
y=tmp-a/b*y;
return ans;
}
ll CRT(ll a[],ll b[],int N)
{
ll n=1;
for(int i=0;i<N;i++)//得到所有除数的乘积
{
n*=a[i];
}
ll res=0;
for(int i=0;i<N;i++)
{
ll m=n/a[i];//得到a[i]以外所有的除数的倍数m
ll mm,y;
//利用扩欧求m的逆元mm
ex_gcd(m,a[i],mm,y);
mm=(mm%a[i]+a[i])%a[i];//最小正整数x为(x%b/gcd(a,b)+b/gcd(a,b))%b/gcd(a,b)
res=(res%n+m*mm*b[i]%n)%n;//线性同余方程组的唯一解res为(m*mm*余数)求和
}
return res;
}
int main()
{
int N;
cin>>N;
for(int i=0;i<N;i++)
{
cin>>a[i]>>b[i];
}
ll res=CRT(a,b,N);
cout<<res;
}
For a detailed explanation of CRT, please see this article by Niuren and oi-wiki