Lucas定理小推论
随便记录点数论小trick
\(Lucas\) 定理的小推论
先来看一道简单的例题:有趣的杨辉三角
题目大意:
给定一个整数 \(n\space(1\le n \le 10^9)\) 和一个质数 \(p\space(2 \le p < 1000)\),求出杨辉三角上第 \(n+1\) 行上有多少个数不能被 \(p\) 整除
分析
看到数据范围很恐怖,众所周知杨辉三角的第 \(n+1\) 行上一共有 \(n+1\) 个数,分别是:
\(n\) 的范围很大,而且要是暴力直接求组合数也得花费时间,显然不能直接暴力求解
但我们注意到 \(p\) 是个很小的质数,而且这题考虑的组合数都是在模 \(p\) 的意义下的,因此我们可以考虑 \(Lucas\) 定理
题目要求这 \(n+1\) 个组合数当中不能被 \(p\) 整除的数有多少个,我们可以考虑一下怎么求可以被 \(p\) 整除的数有多少个,即存在多少个 \(k\in[0,n]\) 有 \(\tbinom{n}{k}\equiv0(mod\space p)\)
回顾一下 \(Lucas\) 定理:当 \(p\) 为质数时,将 \(n\) 与 \(k\) 写成 \(p\) 进制数:
则我们有:
那当什么情况下这个 \(\tbinom{n}{k}\equiv0 \space (mod\space p)\) 呢?
我们将上面的式子分开来看,比如对于一个 \(\tbinom{n_i}{k_i}\) 而言,要让它为 \(0\) ,根据组合数的求法,只有可能是 \(n_i<k_i\) 时才会出现这样的情况,所以只要 \(k_i\le n_i\),这个 \(\tbinom{n}{k}\) 在 \(mod \space p\) 的意义下都不为 \(0\) ,即不被 \(p\) 整除。
那这样的 \(k\) 有多少个呢?根据乘法原理,将 \(n\) 进行 \(p\) 进制拆分后,对于 \(k\) 的 \(p\) 进制第 \(i\) 位来说,\(k_i\) 的取值可以是 \([0,1,2,...,n_i]\) 一共 \(n_i + 1\) 种选法,所以最终答案为:
其实这是个比较出名的定理,如下图:觉得我写的烂的可以自行阅读一下文献

Code:
#include <iostream>
#include <cstdio>
using namespace std;
const int mod = 10000;
int main() {
int n, p, Case = 0;
while (cin >> p >> n, n || p) {
int res = 1;
while (n) {
res = res * (n % p + 1) % mod;
n /= p;
}
printf("Case %d: %04d\n", ++ Case, res);
}
return 0;
}
时间复杂度:对 \(n\) 进行 \(p\) 进制分解的复杂度为 \(O(log_pn)\),乘上测试数据组数,总时间复杂度为 \(O(Tlog_pn)\),完全没问题

浙公网安备 33010602011771号