Lucas 定理
Lucas 定理
若 \(p\) 是质数,则对于任意整数 \(1\leq m \leq n\),有:
例题 \(1\):序列统计
先求当一个序列长度为 \(n\) 时,元素大小都在 \(L\) 至 \(R\) 之间的单调不降元素的序列数量。
等价于把 \(n\) 个相同小球放入 \(R-L+1\) 个盒子里面,盒子可以为空。
常见思路:先把所有盒子里提前放一个小球,等价于把 \(n+R-L+1\) 个小球放入 \(R-L+1\) 个盒子里面,盒子不能为空。隔板,有 \(\dbinom{n+R-L}{R-L}\) 种方式。
现在把序列长度为 \(1\) 至 \(n\) 的方案数都求出来,答案为:
例题 \(2\):SP18878
题目大意
求杨辉三角第 \(n\) 行中偶数个数与奇数个数。
题目分析
我们先求第 \(n\) 行的奇数个数, 用这一行总数减一下就是偶数个数。
等价于求 \(\sum ^{n}_{i=0} \dbinom {n}{i} \mod 2\)。把 \(n,i\) 拆分成二进制数,二进制每一位记为 \(n_k,i_k\)。
根据 Lucas 定理,
当 \(\dbinom {n}{i} \mod 2=1\) 时, 那么所有的 \(n_k,i_k\) 必定满足 \(\dbinom{n_k}{i_k}=1\)。
- 当 \(n_k=0\) 时,有 \(1\) 种情况:\(i_k=0\)。
- 当 \(n_k=1\) 时,有 \(2\) 种情况:\(i_k=0\) 或 \(i_k=1\)。
等价于 \(i\) 为 \(n\) 的子集,故 \(n\) 二进制下若有 \(k\) 个 1,答案就为 \(2^k\)。
例题 \(3\):Gift
很明显,任意一个 \(1\leq i\leq n-1\) 都有 \(\dbinom {a_{b_i}}{a_{b_{i+1}}}\mod 2=1\)。Lucas 显然了。
根据例题 2 的分析,等价于每一个 \(a_{b_{i+1}}\) 都是 \(a_{b_i}\) 的子集,根据题目条件,还要有 \(a_{b_{i+1}}\leq a_{b_i}\)。
在值域上开 dp,没了。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e5 + 5, mod = 1e9 + 7;
int n, a[N], dp[N], res;
signed main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i <= N - 5; i++) dp[i] = 1;
for (int i = 1; i <= n; i++) {
int t = a[i];
for (int j = t - 1 & t; j; j = j - 1 & t) dp[j] = (dp[j] + dp[t]) % mod; // trick:枚举子集
res += dp[t]; res %= mod;
}
cout << (res - n) % mod << endl;
}
例题 \(4\):P4345
根据 Lucas 定理:
容易发现 \(\dbinom{\dfrac{n}{p}}{\dfrac{0}{p}}\) 到 \(\dbinom{\dfrac{n}{p}}{\dfrac{p-1}{p}}\) 是相同的,\(\dbinom{\dfrac{n}{p}}{\dfrac{p}{p}}\) 到 \(\dbinom{\dfrac{n}{p}}{\dfrac{2\times p-1}{p}}\) 也是相同的,依次类推。所以可以对式子进行继续化简,提出相同的公因式。令 \(t_{j}=\sum _{i=0}^{j}\dbinom{n \bmod p}{i}\),则有:
中括号那一堆和最开始求的东西形式一样,可以进行递归处理。复杂度 \(O(\log _p^n)\)。