A few days ago Changchun Network game together Lucas + CRT template problem, did not make out at that time.
Address: http://acm.hdu.edu.cn/showproblem.php?pid=5446
Chinese remainder theorem
In the grandson of the book, there is a question: "This is not known, 33 of the remaining two (divided by 3 2), 55 of the remaining three (divided by 5 3), 77 of the remaining two (divided by 7 2), asked the geometry? "This problem is called" grandson Problem ", the general solution of the problem is called the" Chinese remainder theorem "internationally. The concrete solution is divided into three steps:
1. Find out three numbers: from the common multiple of 3 and 5 to find the smallest 7 of the 1 of the remainder 15, from the common multiple of 3 and 7 to find the smallest 5 of 1 of the remainder 21, and finally from the common multiple of 5 and 7 to find the smallest 3 in addition to 1 70.
2. Multiply by 15 by 2 (2 is the remainder of the final result divided by 7), 21 times 3 (3 is the remainder of the final result divided by 5), in the same vein, 70 times 2 (2 is the remainder of the final result divided by 3), then the three products are added (15*2+21*3+70*2) and 233.
3. Divide 233 by 3,5,7 Three least common multiple 105 to get the remainder 23, i.e. 233%105=23. The remainder of 23 is the decimal number that meets the criteria.
We split the "grandson problem" into a few simple little questions, starting from scratch and trying to speculate on how the ancients deduced the solution.
First, we assume that N1 is a number that satisfies the divide by more than 3 2, such as 2,5,8 and so on, which is an arbitrary number that satisfies 3*k+2 (k>=0). Similarly, we assume that N2 is satisfied by dividing by 5 to 3 of a number, and N3 is satisfying by dividing by 7 more than 2 of a number.
With the previous hypothesis, we start from the angle of N1, known N1 meet divided by 3 more than 2, can make n1+n2 and still meet divided by 3 more than 2? So that the n1+n2+n3 and still meet divided by 3 more than 2?
This involves a most basic mathematical theorem, if there is a%b=c, there is (A+KB)%b=c (k is a nonzero integer), in other words, if the remainder of a division operation is C, then the sum (or subtraction) of the divisor of the dividend and K times is divided by the divisor and the remainder is not changed. This is a very good proof.
On the basis of this theorem, if N2 is a multiple of 3, N1+N2 will still be satisfied by dividing by 3 + 2. Similarly, if N3 is also a multiple of 3, then N1+N2+N3 is satisfied divided by 3 + 2. This is from the perspective of N1, and then from the perspective of n2,n3, we can deduce the following three points:
- To make the n1+n2+n3 and meet divided by more than 3 2,n2 and N3 must be a multiple of 3.
- To make the n1+n2+n3 and meet divided by more than 5 3,n1 and N3 must be a multiple of 5.
- To make the n1+n2+n3 and meet divided by more than 7 2,n1 and N2 must be a multiple of 7.
Thus, to make the n1+n2+n3 and as a final solution to the "grandson problem", it is necessary to satisfy:
- N1 divided by 3 and 2, and is common multiple of 5 and 7.
- N2 divided by 5 and 3, and is common multiple of 3 and 7.
- N3 divided by 7 and 2, and is common multiple of 3 and 5.
Therefore, the essence of Sun Tzu's solution is to find a common multiple of 5 and 7 divided by 3 2 N1, from 3 and 7 of common multiple to find a number divided by 5 3 N2, from the common multiple of 3 and 5 to find a number divided by 7 2 N3, and then add three numbers to get the solution. In the search for n1,n2,n3 and a small trick, take N1 as an example, not from 5 and 7 of the common multiple directly to find a number divided by 3 2, but first to find a number divided by 3 more than 1, and then multiplied by 2.
Here again there is a mathematical formula, if a%b=c, then (a*k)%B=A%B+A%B+...+A%B=C+C+...+C=KC (k>0), that is, if the remainder of a division is C, then the remainder of dividend's K-fold divide with the divisor is KC. has been proven in the expanded formula.
Finally, we have to be clear that N1+N2+N3 is only a solution to the problem, not the smallest solution. How to get the minimum solution? All we need to do is to minimize the 3,5,7 common multiple 105 from the maximum. The truth is the theorem "if A%b=c, there is (A-KB)%b=c". So (N1+N2+N3)%105 is the ultimate minimum solution.
Lucas theorem is used to find the value of C (n,m) mod p, p is the prime number
A, B is a non-negative integer and P is a prime number. AB is written in P-system: a=a[n]a[n-1]...a[0],b=b[n]b[n-1]...b[0].
Then the combination of C (A, B) and C (A[n],b[n]) *c (a[n-1],b[n-1]) *...*c (a[0],b[0]) mod p is the same
First we notice that n= (ak...a2,a1,a0) p = (AK...A2,A1) p * p + a0
= [n/p]*p+a0
and m=[m/p]+b0
As long as we can prove C (n,m) =c ([n/p],[m/p]) * C (a0,b0) (mod p)
The rest of the work can be done by inductive method
We know to any prime number p: (1+x) ^p = = 1+ (x^p) (mod p)
It must be a prime number here.
In the case of modulo p
The coefficients of the x^m on the left and right sides of the upper side must be identical to the modulus P (why), where the coefficients of the left x^m are C (n,m) and because A0 and B0 are less than P
The X^m on the Right (= x^ ([m/p]*p) +b0) must be multiplied by x^ ([m/p]*p) and x^b0 (that is, in i=[m/p], j=b0) so we have
C (n,m) =c ([n/p],[m/p]) * C (a0,b0) (mod p)
Here is the code
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <cstdlib>5#include <Set>6#include <vector>7#include <algorithm>8 #definell Long Long9 using namespacestd;Ten ll N,m,sum,sumn; One intQ; All primes[ A][3]; - -ll CRT (intq) the { - ll temp, t; - for(intI=0; i< Q; i++) - { +t = sum/primes[i][0]; -temp =T; + while(temp%primes[i][0]! = primes[i][1]) A { attemp = temp+T; - } -primes[i][2] =temp; - } - for(inti =0; i< Q; i++) - { inSumn + = (primes[i][2]%sum); - } to returnsumn%sum; + } - the ll Qpow (ll a,ll b,ll p) * { $ intans;Panax Notoginseng for(ans=1; b;b>>=1, a=a*a%p) - if(b&1) ans=ans*a%p; the returnans; + } A the ll Getc (ll n,ll m,ll p) + { - if(n<m)return 0; $ if(m>n-m) m=n-m; $ll s1=1, s2=1; - for(intI=0; i<m;i++) - { theS1=s1* (n-i)%p; -s2=s2* (i+1)%p;Wuyi } the returnS1*qpow (s2,p-2, p)%p; - } Wu - ll Lucas (ll n,ll m,ll p) About { $ if(m==0)return 1; - returnGETC (n%p,m%p,p) *lucas (n/p,m/p,p)%p; - } - A intMain () + { the intT; -scanf"%d", &T); $ while(t--) the { thesum =1; thesumn=0; thescanf"%lld%lld%d", &n,&m, &q); - //printf ("%lld%lld%d\n", N, M, q); in for(inti =0; i< Q; i++) the { thescanf"%lld", &primes[i][0]); AboutSum *= primes[i][0]; the //printf ("%lld\n", Primes[i][0]); theprimes[i][1] = Lucas (n,m,primes[i][0]); the } + /*for (int i= 0; i< q; i++) - { the printf ("%lld\n", primes[i][1]);Bayi } the */ theprintf"%lld\n", CRT (q)); - } - the return 0; the}
HDU5446
HDU5446 Unknown Treasure