"Theorem Overview"
The Chinese remainder theorem (Sun Tzu's theorem) is a method to solve the same-remainder group in ancient China. is an important theorem in number theory. One-element linear congruence Equation group problem was first seen in the Chinese Northern and Southern Dynasties (A.D. 5th century) of the mathematical work "grandson of the book" Volume 26th, called "Things do not know the number" problem, the original is as follows: There is no known its number, 33 of the remaining two, 55 of the remaining three, 77 of the remaining two. Asking for geometry? That is, an integer divided by three more than two, divided by five more than three, divided by seven more than two, the integer is asked. For the first time, the problem of congruence equations and the solution of the above specific problems are mentioned in the book of grandchildren, so the Chinese remainder theorem is also called the Sun Tzu Theorem in Chinese mathematical literature.
"Seeking inverse element"
The meaning of the inverse element: in the sense of modulo p, a number a if there is an inverse of x, then divide by a is the equivalent of multiplying by X. Ax≡1 (mod p).
A sufficient and necessary condition for a number with an inverse is gcd (a,p) = 1, at which time the inverse element exists only.
Method 1: Fermat theorem for inverse element,p is prime , and gcd (a,p) =1
In the case of a modulus of p, there is a Fermat theorem
Ap-1≡1 (mod p)
Then A * ap-2≡1 (mod p)
So the inverse of a is a ap-2, with a fast power to seek.
#include <iostream>using namespacestd;Long LonggcdLong LongALong Longb) { if(b = =0)returnA; returnGCD (b, a%b);}Long LongQpow (Long LongALong LongNLong LongMoD) { Long LongAns =1; //if the binary of n is the last one is 1 result participation arithmetic//because if it is 0, then the term is multiplied by any number or that number after the power operation, which does not affect the result while(N >0){ if(N &1) ans= (ans* a)%MoD; A= (a*a)% MoD;//double the base.N >>=1;//Shift } returnans; }//Long LongInvele (Long LongALong LongMoD) { //if A and modulus are not coprime, then there must be no inverse element . if(GCD (a,mod)! =1|| MoD <2)return-1; returnQpow (a,mod-2, MoD);}intMain () {Long Longb; intx, y; while(cin>>a>>b) {cout<<invele (b) <<Endl; }}
Method 2: Expand Euclidean (efficient)
typedef Longlong ll; void extgcd (ll a,ll b,ll& d,ll& x,ll& y) { if(!b) {d=a; x=1; y=0 ;} Else {EXTGCD (b,a%b,d,y,x); y-=x* (A/b);}} ll Inverse (ll a,ll N) { ll d,x,y; EXTGCD (a,n,d,x,y); return d==1? (x+n)%n:-1;}
Method 3: Euler theorem for inverse element (seldom used)
Euler's theorem is needed when modulo p is not a prime number.
Inverse Yuan Dozen table:
typedef Longlong ll; Const int 5 ; int void inverse (intint p) { inv[11 ; for (int i=2; i<=n; + +i) {= (ll) (P/i) * inv[p%i]% p; }}
"Solution Equation Set"
According to the theorem overview and solution, the following methods are obtained
intCRT (intA[],intM[],intN) { intM =1; intAns =0; for(intI=1; i<=n; i++) M*=M[i]; for(intI=1; i<=n; i++) { intx, y; intMi = M/M[i]; Extend_euclid (Mi, M[i], x, y); Ans= (ans + Mi * x * a[i])%M; } if(Ans <0) ans + =M; returnans;}
"Extending the Chinese remainder theorem"
When the modulus mi 22 coprime with the above solution, when the modulus is not determined whether 22 coprime it?
Excerpt from blog: 8050018
This is the case with the idea of a 22 merger, assuming that the following two equations are to be combined
So get
The solution of the smallest positive integer solved by the extended Euclidean algorithm, which is then brought into
The results obtained after merging into one equation are
In this way, the solution of the same residual equations can be obtained in the end.
#include <iostream>#include<string.h>#include<stdio.h>using namespaceStd;typedefLong LongLL;Const intN =1005; LL A[n], m[n]; ll GCD (ll A,ll b) {returnB? GCD (b, a%b): A;} voidExtend_euclid (ll A, ll B, ll &x, LL &y) { if(b = =0) {x=1; Y=0; return; } extend_euclid (b, a%b, x, y); LL tmp=x; X=y; Y= tmp-(A/b) *y;} ll Inv (ll A, ll b) {ll d=gcd (A, b); if(d! =1)return-1; LL x, y; Extend_euclid (A, B, X, y); return(x% b + B)%b;} BOOLMerge (ll A1, LL M1, LL A2, ll m2, ll &a3, LL &m3) {LL D=GCD (M1, M2); LL C= A2-A1; if(c% d)return false; C= (c% m2 + m2)%m2; M1/=D; M2/=D; C/=D; C*=INV (M1, M2); C%=m2; C*= M1 *D; C+=A1; M3= M1 * m2 *D; A3= (c% m3 + m3)%m3; return true;} ll CRT (ll a[], LL m[],intN) {LL A1= a[1]; LL M1= m[1]; for(intI=2; i<=n; i++) {LL A2=A[i]; LL m2=M[i]; LL M3, A3; if(!Merge (A1, M1, A2, M2, A3, m3))return-1; A1=A3; M1=m3; } return(A1% M1 + M1)%M1;} intMain () {intN; while(SCANF ("%d", &n)! =EOF) { for(intI=1; i<=n; i++) scanf ("%i64d%i64d", &m[i], &A[i]); LL ans=CRT (A, M, N); printf ("%i64d\n", ans); } return 0;}
Chinese remainder theorem