The extended Lucas theorem is used to find the following formula (where \ (p\) is not necessarily prime):
\[c_n^m\ mod\ P\]
We will divide this problem from the overall to the local three levels to solve.
Level One: the original problem
First , the \ (p\) is decomposed by the mass factor:
\[p=\prod_i p_i^{k_i} \]
Obviously \ (p_i^{k_i}\) is 22 coprime, so if you find out \ (c_n^m\ mod\ p_i^{k_i}\), you can construct a number of shapes such as \ (c_n^m=a_i\ mod\ p_i^{k_ i}\) , and then the Chinese remainder theorem can be used to solve the equation.
Level Two: Combination number modulus prime power
Now the problem is translated into the following equation (where \ (p\) is prime):
\[c_n^m\ mod\ p^k \]
The brain complements the combination number formula \ (c_n^m=\frac{n!} {m!\times (n-m)!} \) , found due to \ (m!\) and \ ((n-m)!\) may contain a mass factor \ (p\) , so they cannot be directly asked for the inverse of \ (p^k\) . At this point we can \ (n!\) , \ (m!\) , \ ((n-m)!\) The mass factor \ (p\) all come up, and finally take it back. The \ (k1\) is \ (n!\) medium-quality factor \ (p\) , \ (k2\) , \ ( k3\) similarly):
\[\frac{\frac{n!} {P^{K1}}} {\frac{m!} {p^{k2}}\times \frac{(n-m)!} {P^{K3}}} \times p^{k1-k2-k3}\]
\ (\frac{m!} {p^{k2}}\) and \ (\frac{(N-M)!} {p^{k3}}\) and \ (p^k\) are coprime, which can be directly obtained from the inverse element.
Level three: factorial elimination of mass factor after modulus prime power
Now look at how to calculate the equation of the form as follows.
\[\frac{n!} {p^{a}}\ mod\ p^k\]
First consider how to calculate \ (n!\ mod\ p^k\)
For example:\ (n=22\),\ (p=3\),\ (k=2\)
Write this out:
\(22!=1\times 2\times 3\times 4\times 5\times 6\times 7\times 8\times 9\times 10 \times 11\times 12\times 13\times 14\time s 15\times 16\times 17\times 18\times \times (\times) \times 22\)
Extract the multiples of all \ (p\) (i.e. \ (3\)) to get:
\ (22!=3^7 \times (1\times 2\times 3\times 4\times 5\times 6\times 7) \times (1\times 2\times 4\times 5\times 7\times 8\times \times 11\times 13\times 14\times 16\times 17\times (\times \times 22) \)
It can be seen that the above is divided into three parts: the first part is the power of \ (3\) , the number of times is less than or equal to \ (22\) of \ (3\) the number of multiples, that is \ (\lfloor\frac{n}{p}\ rfloor\)
The second part is a factorial \ (7!\), i.e. \ (\lfloor\frac{n}{p}\rfloor!\), which can be resolved recursively
The third part is the product of \ (n!\) with the portion of \ (p\) coprime, which has the following properties:
\(1\times 2\times 4\times 5\times 7\times 8\equiv10 \times 11\times 13\times 14\times 16\times 17\ mod\ p^k\)
In the meaning of modulo \ (3^2\) \ (10\) and \ (1\) congruence,\ (11\) and \ (2\) congruence ... It's more obvious that you write the following formula
(\ (t\) is any positive integer)
\[\prod_{i, (I,p) =1}^{p^k}i\equiv\prod_{i, (i,p) =1}^{p^k} (i+tp^k) \ mod\ P^k\]
\ (\prod_{i, (i,p) =1}^{p^k}i\) A total cycle of \ (\lfloor\frac{n}{p^k}\rfloor\) times, violence to seek out \ (\prod_{i, (i,p) =1 }^{p^k}i\) and then uses the fast power to seek its power of \ (\lfloor\frac{n}{p^k}\rfloor\) .
And finally take up \ (19\times \times 22\)(ie , \prod_{i, (i,p) =1}^{n\mod\ p^k}i\), obviously the length of this paragraph must be less than \ (p^k \), violence can be multiplied.
The product of the above three parts is \ (n!\). The final requirement is \ (\frac{n!} {p^{a}}\ mod\ p^k\), the denominator is all contributed by the first and second parts of the above (Part III and \ (p\) coprime). The second part of the recursive calculation of the time has been removed from the second section of the Factor \ (p\), so the final answer is the second part of the recursive return of the result and the third part of the product (not related to the first part).
Easy to understand with code:
ll fac(const ll n, const ll p, const ll pk){ if (!n) return 1; ll ans = 1; for (int i = 1; i < pk; i++) if (i % p) ans = ans * i % pk; ans = power(ans, n / pk, pk); for (int i = 1; i <= n % pk; i++) if (i % p) ans = ans * i % pk; return ans * fac(n / p, p, pk) % pk;}
Level Two: Combination number modulus prime power
Back to the equation.
\[\frac{\frac{n!} {P^{K1}}} {\frac{m!} {p^{k2}}\times \frac{(n-m)!} {P^{K3}}} \times p^{k1-k2-k3}\]
It can be easily converted into code (note I to open long long):
ll C(const ll n, const ll m, const ll p, const ll pk){ if (n < m) return 0; ll f1 = fac(n, p, pk), f2 = fac(m, p, pk), f3 = fac(n - m, p, pk), cnt = 0; for (ll i = n; i; i /= p) cnt += i / p; for (ll i = m; i; i /= p) cnt -= i / p; for (ll i = n - m; i; i /= p) cnt -= i / p; return f1 * inv(f2, pk) % pk * inv(f3, pk) % pk * power(p, cnt, pk) % pk;}
Level One: the original problem
Complete code (title: Valley 4720 "template" extension Lucas):
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include < Climits> #include <cmath>using namespace std;namespace zyt{const int N = 1E6; typedef long Long LL; ll N, M, p; Inline ll Power (ll A, ll B, const LL p = Llong_max) {ll ans = 1; while (b) {if (b & 1) ans = ans * a% P; A = a * a% p; b >>= 1; } return ans; } ll FAC (const ll N, const ll p, Const LL PK) {if (!n) return 1; ll ans = 1; for (int i = 1; i < PK; i++) if (i% p) ans = ans * I% PK; ans = power (ans, n/pk, PK); for (int i = 1; I <= n PK; i++) if (i% p) ans = ans * I% PK; return ans * FAC (n/p, p, PK)% PK; } ll EXGCD (const ll A, const LL B, LL &x, ll &y) {if (!b) {x = 1, y = 0; return A; } ll xx, yy, G = EXGCD (b, a% B, xx, yy); x = yy; y = xx-a/b * YY; return g; } ll INV (const LL A, const LL p) {ll x, y; EXGCD (A, p, X, y); Return (x% p + p)% p; } ll C (const ll N, const ll m, const LL p, Const LL PK) {if (n < m) return 0; ll f1 = FAC (n, p, pk), F2 = FAC (M, p, pk), F3 = FAC (N-M, p, pk), cnt = 0; for (ll i = n; i; I/= p) cnt + = i/p; for (ll i = m; i; I/= p) cnt-= i/p; for (ll i = n-m; i; I/= p) cnt-= i/p; Return F1 * INV (F2, PK)% PK * INV (F3, PK)% PK * Power (p, CNT, PK)% PK; } ll A[n], c[n]; int cnt; inline ll CRT () {ll M = 1, ans = 0; for (int i = 0; i < cnt; i++) M *= c[i]; for (int i = 0; i < cnt; i++) ans = (ans + a[i] * (M/c[i])% m * INV (M/c[i], c[i])% m)% m; return ans; } ll Exlucas(const ll N, const ll m, ll P) {ll tmp = sqrt (p); for (int i = 2; p > 1 && i <= tmp; i++) {ll tmp = 1; While (p% i = = 0) p/= I, TMP *= i; if (tmp > 1) a[cnt] = C (n, M, I, TMP), c[cnt++] = tmp; } if (P > 1) a[cnt] = C (n, M, p, p), c[cnt++] = p; return CRT (); } int work () {Ios::sync_with_stdio (false); CIN >> n >> m >> p; cout << Exlucas (n, M, p); return 0; }}int Main () {return zyt::work ();}
Knowledge Summary Extended Lucas theorem (Exlucas)