威尔逊定理

1 威尔逊定理

内容:
对于素数 p(p1)!1(modp).

推论:
(p1)!0(mod p),(p>4p 为合数)

计算余数算法:

实现 n! % p.

时间复杂度: 时间复杂度为 O(p+logpn). 如果需要多次调用函数,则可以在函数外部进行预计算,于是计算 (n!)p 的时间复杂度为 O(logpn).

int factmod(int n, int p) {
  vector<int> f(p);
  f[0] = 1;
  for (int i = 1; i < p; i++) f[i] = f[i - 1] * i % p;
  int res = 1;
  while (n > 1) {
    if ((n / p) % 2) res = p - res;
    res = res * f[n % p] % p;
    n /= p;
  }
  return res;
}

2 Legendre 公式:

n! 中含有的素数 p 的幂次 vp(n!) 为:

vp(n!)=i=1npi=nSp(n)p1
其中 Sp(n)p 进制下 n 的各个数位的和。

特别地,阶乘中 2 的幂次是 v2(n!)=nS2(n).

O(logn) 实现:

int multiplicity_factorial(int n, int p) {
  int count = 0;
  do {
    n /= p;
    count += n;
  } while (n);
  return count;
}

3 Kummer 定理:

p 在组合数
(mn) 中的幂次,恰好是 p 进制下 m 减掉 n 需要借位的次数。


vp((mn))=Sp(n)+Sp(mn)Sp(m)p1

特别地,组合数中 2 的幂次是
v2((mn))=S2(n)+S2(mn)S2(m).

4 Wilson 定理的推广:

对于素数 p和正整数 q(pq!)p±1(modpq).

(pq!)p{1,(p=2)(q3),1,otherwise.