[Luo Gu P3807] [template] Lucas Theorem

\({n+m \choose n}\bmod p\)

Lucas (Lucas) Theorem

\[{n \choose m}\equiv{n\bmod p \choose m\bmod p}\times{\lfloor{n\over p}\rfloor \choose \lfloor{m\over p}\rfloor}\pmod p \]

Proof (thanks Lance1ot)

First, we need to prove

\[{p\choose i}\equiv{p\over i}{p-1\choose i-1}\equiv 0\pmod p,(1\le i\le p-1) \]

by

\[{p\choose i}={p!\over i!(p-i)!}={p\over i} {(p-1)!\over(i-1)!(p-1-i+1)!} {p\over i} {(p-1)!\over(i-1)!(p-i)!}={p\over i}{p-1\choose i-1} \]

Proved.
Then according to the nature and the binomial theorem, we immediately draw

\[(1+x)^p\equiv {p\choose0}1^p+{p\choose1}x^{2}+....+{p\choose p}x^p\equiv {p\choose0}1^px^0+{p\choose p}1^0x^p\equiv 1+x^p\pmod p \]

Then we will be asked for evidence

\[{a\choose b}\equiv {a_0\choose b_0}{a_1p\choose b_1p}{a_2p^2\choose b_2p^2}\dots\pmod p \]

Order \ (a = lp + r,
b = sp + j \) Prove \ ({a \ choose b} \ equiv {l \ choose s} {r \ choose j} \ pmod p \) and then using the properties of recursive solution to it.
Continue to proceed from the secondary item Theorem

\[(1+x)^a=(1+x)^{lp} \cdot (1+x)^r \]

Then expand \ ((1 + x) ^ {lp} \)

\[(1+x)^{lp} \equiv ((1+x)^p)^l \equiv (1+x^p)^l\pmod p \]

\[\therefore (1+x)^a \equiv (1+x^p)^l(1+x)^r\pmod p \]

Observation \ (x ^ b \) coefficients

\[\because {a^b\choose x^b}\equiv{l\choose s}x^{sp}{r\choose j}x^j\pmod p \]

\[\therefore {a\choose b}x^b \equiv {l\choose s}{r\choose j}x^b\pmod p \]

\[\therefore {a\choose b}\equiv {l\choose s}{r\choose j} \equiv {\lfloor {a\over p} \rfloor\choose \lfloor {b\over p} \rfloor}{a\bmod p\choose b\bmod p}\pmod p \]

Is proved

achieve

#include <cstdio>

#define ll long long
#define re register
#define il inline
#define gc getchar
#define pc putchar

template <class T>
void read(T &x) {
  re bool f = 0;
  re char c = gc();
  while ((c < '0' || c > '9') && c != '-') c = gc();
  if (c == '-') f = 1, c = gc();
  x = 0;
  while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = gc();
  f && (x = -x);
}

template <class T>
void print(T x) {
  if (x < 0) pc('-'), x = -x;
  if (x >= 10) print(x / 10);
  pc((x % 10) ^ 48);
}

template <class T>
void prisp(T x) {
  print(x);
  pc(' ');
}
template <class T>
void priln(T x) {
  print(x);
  pc('\n');
}

ll fac[100005];

ll pow(ll b, int t, ll p) {
  ll r;
  for (r = 1; t; t >>= 1, b = (b * b) % p)
    if (t & 1) r = (r * b) % p;
  return r;
}

ll C(ll n, ll m, ll p) {
  if (m > n) return 0;
  return (fac[n] * pow(fac[m], p - 2, p) % p) * pow(fac[n - m], p - 2, p) % p;
}

ll lucas(ll n, ll m, ll p) {
  if (m == 0) return 1;
  return C(n % p, m % p, p) * lucas(n / p, m / p, p) % p;
}

int main() {
  int t;
  read(t);
  while (t--) {
    ll n, m, p;
    read(n);
    read(m);
    read(p);
    fac[0] = 1;
    for (int i = 1; i <= p; ++i) fac[i] = (fac[i - 1] * i) % p;
    priln(lucas(n + m, m, p));
  }
}

Guess you like

Origin www.cnblogs.com/water-lift/p/12561427.html