Chinese remainder theorem, aka grandson Theorem O (* ≧▽≦) Mitsujo
What problems can be solved?
Problem:
A bunch of things.
3 x 3 left 2
5 x 5 left 3
7 x 7 left 2
Ask how many of this item
To solve this problem, we need to construct an answer
We need to construct this answer.
5*7*INV (5*7, 3)% 3 = 1
3*7*INV (3*7, 5)% 5 = 1
3*5*INV (3*5, 7)% 7 = 1
These 3 are not correct, don't tell me inverse yuan you forget (*′? ' *), forget the people please read the previous chapters review
Then both sides multiply the number you need
2 * 5*7*INV (5*7, 3)% 3 = 2
3 * 3*7*INV (3*7, 5)% 5 = 3
2 * 3*5*INV (3*5, 7)% 7 = 2
Make
A = 2 * 5*7*INV (5*7, 3)
b = 3 * 3*7*INV (3*7, 5)
c = 2 * 3*5*INV (3*5, 7)
So
A% 3 = 2
B% 5 = 3
C% 7 = 2
Actually, the answer is a+b+c.
Because
a%5 = a%7 = 0 Because A is a multiple of 5 and a multiple of 7
b%3 = b%7 = 0 because B is a multiple of 3 and a multiple of 7
c%3 = c%5 = 0 because C is a multiple of 3 and a multiple of 5
So
(A + B + c)% 3 = (a% 3) + (b% 3) + (c% 3) = 2 + 0 + 0 = 2
(A + B + c)% 5 = (a% 5) + (b% 5) + (c% 5) = 0 + 3 + 0 = 3
(A + B + c)% 7 = (a% 7) + (b% 7) + (c% 7) = 0 + 0 + 2 = 2
You see, the answer is not a+b+c (?? Omega?)??, fully satisfying test instructions
But the answer, more than one, has infinity, and every 105 is an answer (105 = 3 * 5 * 7)
According to the calculation, the answer equals 233,233%105 = 23
If the question asks you the smallest answer, it's 23.
The following copy from Baidu Encyclopedia
The Chinese remainder theorem gives the following one-element linear congruence equations: Chinese remainder theorem description: hypothetical integer
m1,
m2,...,
mn 22 Coprime, then an arbitrary integer:
a1,
a2,...,
an, the equation set (S) has a solution, and the general solution can be constructed in the following way: Set is an integer
m1,
m2,...,
mThe product of N, and is set apart
mOutside of I
N-a product of 1 integers. This is the inverse of the element.
The general solution form is in the sense of modulo m, the equation set (S) has only one solution: I know you just code (*?▽? *), toss code, and I Throw
1//n equation: x=a[i] (mod m[i]) (0<=I<N) 2 ll China (int n, ll *a, ll *m) {3 ll m = 1, ret = 0; 4 for (int i = 0; i < n; i + +) M *= m[i]; 5 for (int i = 0; i < n; i + +) {6 LL w = m/m[i]; 7 ret = (ret + w * INV (W, m[i]) * a[i])% M; 8 } 9
Do you want to try hackers a question?
POJ 1006
http://poj.org/problem?id=1006
Problem Description:
People from birth have physical, emotional and intellectual three physiological cycles, respectively, 23, 28 and 33 days. One day in a cycle is the peak, on this day, the person in the corresponding aspect (physical, emotional or intellectual) performance best. Typically, the peaks of these three cycles will not be the same day. Now give three dates, respectively, corresponding to the physical, emotional, intellectual peak of the date. Then give a starting date, asking from this day, to calculate the minimum number of days after the three peaks at the same time.
Analysis:
Because 23 = 23
28 = 2*2*7
33 = 3*11
Meet the 22 coprime relationship, so the direct set of templates is good
AC Code:
#include <cstdio>
typedef long Long LL;
const int N = 100000 + 5;
void Ex_gcd (ll A, ll B, LL &x, LL &y, ll &d) {
if (!b) {d = a, x = 1, y = 0;}
else{
EX_GCD (b, a% B, y, X, D);
Y-= x * (A/b);
}
}
LL INV (ll T, ll P) {//If not present, return-1
LL d, x, y;
EX_GCD (t, p, X, y, D);
return d = = 1? (x% p + p)% p:-1;
}
ll China (int n, ll *a, ll *m) {//Chinese remainder theorem
LL M = 1, ret = 0;
for (int i = 0; i < n; i + +) M *= m[i];
for (int i = 0; i < n; i + +) {
LL w = m/m[i];
RET = (ret + w * INV (W, m[i]) * a[i])% m;
}
Return (ret + m)% m;
}
int main () {
LL p[3], r[3], D, ans, MOD = 21252;
int cas = 0;
P[0] = 23; P[1] = 28; P[2] = 33;
while (~SCANF ("%i64d%i64d%i64d%i64d", &r[0], &r[1], &r[2], &d) && (~r[0] | | ~r[1] | | ~r[2] | | ~d)) {
Ans = ((China (3, R, p)-D)% mod + MoD)% MoD;
printf ("Case%d:the next triple peak occurs in%i64d days.\n", ++cas, ans? ans:21252);
}
}
1 #include <cstdio> 2 typedef long Long LL; 3 const int N = 100000 + 5; 4 void Ex_gcd (ll A, ll B, LL &x, LL &y, ll &d) {5 if (!b) {d = a, x = 1, y = 0;} 6 else{7 ex_ GCD (b, a% B, y, X, D); 8 Y-= x * (A/b); 9}10}11 ll inv (ll T, ll P) {//If not present, return-1 LL D, X, y;13 ex_gcd (T, p, X, y, d); return d = = 1? (x% p + p)% p: -1;15}16 LL China (int n, ll *a, ll *m) {//Chinese remainder theorem ~ m = 1, ret = 0;18 for (int i = 0; i < n ; i + +) M *= m[i];19 for (int i = 0; i < n; i + +) {$ LL w = m/m[i];21 ret = (ret + w * INV (W, M[i]) * A[i])% m;22}23 return (ret + M)% m;24}25 int main () {$ LL p[3], r[3], D, ans, MOD = 21252;27 int CAs = 0;28 P[0] = 23; P[1] = 28; P[2] = 33;29 while (~scanf ("%i64d%i64d%i64d%i64d", &r[0], &r[1], &r[2], &d) && (~r[0] | | ~r[1] || ~R[2] | | ~d)) {3 ans = ((China (, R, p)-D)% mod + MoD)% mod;31 printf ("Case%d:the NExt Triple Peak occurs in%i64d days.\n ", ++cas, ans? ans:21252); 32}33 34}
Of course, this Chinese remainder theorem is only the foundation, facing the more formidable enemy, we must have the stronger weapon
For example,m1,m2, ...,mn 22 does not guarantee coprime, spicy how to do (っ°д°) our store
Don't be afraid, look at me and throw the code.
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 typedef long Long LL; 5 typedef pair<ll, ll> PLL; 6 PLL Linear (ll a[], LL b[], LL m[], int n) {//Solution a[i]x = b[i] (mod m[i]), a total of n linear equations group 7 LL x = 0, M = 1; 8 for (in t i = 0; I < n; i + +) {9 LL a = a[i] * m, B = b[i]-a[i]*x, d = gcd (M[i], a), if (b% d! = 0) return PLL (0,-1);//The answer does not exist, return- 1 LL t = b/d * INV (A/d, m[i]/d)% (m[i]/d); x = x + m*t;13 M *= m[i]/d;14 }15 x = (x% m + m)% m The return PLL (x, m);//x is the answer, M is the last LCM value 17}
This code I do not give an explanation (because I will not, wow hahaha ╰ (*°▽°*) ╯)
If you meet the questions you need, go to set up a template.
(Want to know the code principle of Go to Baidu Bar, or to see "Challenge Program Design Contest", my template is copied from the book through the change of Brother Jie)
Like Poj 2891.
http://poj.org/problem?id=2891
"The main topic"
Give the K-mode equation Group: x mod ai = ri. To find the minimum positive value of x. If there is no such x, then output-1.
"Problem Analysis"
Because the AI and RI do not satisfy the nature of 22 coprime, the Chinese remainder theorem can not be solved directly in this problem.
Spicy .... Happy set of this template bar
The AC code is as follows:
#include <cstdio>
#include <algorithm>
using namespace Std;
typedef long Long LL;
typedef pair<ll, ll> PLL;
LL a[100000], b[100000], m[100000];
ll GCD (ll A, ll b) {
Return b? GCD (b, a%b): A;
}
void Ex_gcd (ll A, ll B, LL &x, LL &y, ll &d) {
if (!b) {d = a, x = 1, y = 0;}
else{
EX_GCD (b, a% B, y, X, D);
Y-= x * (A/b);
}
}
LL INV (ll T, ll P) {//If not present, return-1
LL d, x, y;
EX_GCD (t, p, X, y, D);
return d = = 1? (x% p + p)% p:-1;
}
PLL linear (ll a[], LL b[], LL m[], int n) {//Solution a[i]x = b[i] (mod m[i]), n systems of linear equations in total
LL x = 0, m = 1;
for (int i = 0; i < n; i + +) {
LL a = a[i] * m, B = b[i]-a[i]*x, d = gcd (M[i], a);
if (b% d! = 0) return PLL (0,-1);//answer, not present, return-1
LL t = b/d * INV (A/d, m[i]/d)% (M[I]/D);
x = x + m*t;
M *= m[i]/d;
}
x = (x% m + m)% m;
return PLL (x, m);//return x is the answer, M is the last LCM value
}
int main () {
int n;
while (scanf ("%d", &n)! = EOF) {
for (int i = 0; i < n; i + +) {
A[i] = 1;
scanf ("%d%d", &m[i], &b[i]);
}
PLL ans = Linear (A, B, M, n);
if (Ans.second = =-1) printf (" -1\n");
else printf ("%i64d\n", Ans.first);
}
}
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 typedef long Long LL; 5 typedef pair<ll, ll> PLL; 6 LL a[100000], b[100000], m[100000]; 7 ll GCD (ll A, ll b) {8 return B? gcd (b, a%b): A; 9}10 void Ex_gcd (ll A, ll B, LL &x, LL &y, ll &d) {11 if (!b) {d = a, x = 1, y = 0;} Else{13 EX_GCD (b, a% B, y, X, D), Y-= x * (A/b),}16}17 ll inv (ll T, ll P) {//If not present, return- 1 LL D, X, y;19 ex_gcd (T, p, X, y, d); return d = = 1? (x% p + p)% p: -1;21}22 PLL Linear (ll a[], LL b[], LL m[], int n) {//Solution a[i]x = b[i] (mod m[i]), total n linear equation Group x = 0, M = 1;24 for (int i = 0; i < n; i + +) {LL a = a[i] * m, B = b[i]-a[i]*x, d = gcd (M[i], a); 26 if (b% d! = 0) return PLL (0,-1);//answer, not present, return-1 LL t = b/d * INV (A/d, m[i]/d)% (m[i]/d); x = x + m*t ; M *= m[i]/d;30}31 x = (x% m + m)% m;32 return PLL (x, m);//return x is the answer, M is the last LCM value 33}34 int main () {38 int n;36 while (scanf ("%d", &n)! = EOF) {PNS for (int i = 0; i < n; i + +) A[i] = 1;39 scanf ("%d%d", &m[i], &b[i]);}41 PLL ans = linear (A, B, M, n); 42 if (Ans.second = =-1) printf (" -1\n"); ("%i64d\n", Ans.first); 44}45}
#include <cstdio>
#include <algorithm>
using namespace Std;
typedef long Long LL;
typedef pair<ll, ll> PLL;
LL a[100000], b[100000], m[100000];
ll GCD (ll A, ll b) {
Return b? GCD (b, a%b): A;
}
void Ex_gcd (ll A, ll B, LL &x, LL &y, ll &d) {
if (!b) {d = a, x = 1, y = 0;}
else{
EX_GCD (b, a% B, y, X, D);
Y-= x * (A/b);
}
}
LL INV (ll T, ll P) {//If not present, return-1
LL d, x, y;
EX_GCD (t, p, X, y, D);
return d = = 1? (x% p + p)% p:-1;
}
PLL linear (ll a[], LL b[], LL m[], int n) {//Solution a[i]x = b[i] (mod m[i]), n systems of linear equations in total
LL x = 0, m = 1;
for (int i = 0; i < n; i + +) {
LL a = a[i] * m, B = b[i]-a[i]*x, d = gcd (M[i], a);
if (b% d! = 0) return PLL (0,-1);//answer, not present, return-1
LL t = b/d * INV (A/d, m[i]/d)% (M[I]/D);
x = x + m*t;
M *= m[i]/d;
}
x = (x% m + m)% m;
return PLL (x, m);//return x is the answer, M is the last LCM value
}
int main () {
int n;
while (scanf ("%d", &n)! = EOF) {
for (int i = 0; i < n; i + +) {
A[i] = 1;
scanf ("%d%d", &m[i], &b[i]);
}
PLL ans = Linear (A, B, M, n);
if (Ans.second = =-1) printf (" -1\n");
else printf ("%i64d\n", Ans.first);
}
}
ACM Number Theory Tour--Chinese remainder theorem