Lucas 定理

Lucas 定理

p 是质数,则对于任意整数 1mn,有:

(nm)(nmodpmmodp)×(mpnp)(modp)

例题 1序列统计

先求当一个序列长度为 n 时,元素大小都在 LR 之间的单调不降元素的序列数量。

等价于把 n 个相同小球放入 RL+1 个盒子里面,盒子可以为空。

常见思路:先把所有盒子里提前放一个小球,等价于把 n+RL+1 个小球放入 RL+1 个盒子里面,盒子不能为空。隔板,有 (n+RLRL) 种方式。

现在把序列长度为 1n 的方案数都求出来,答案为:

(1+RLRL)+(2+RLRL)++(n+RLRL)=(n+RL+1RL+1)1

例题 2SP18878

题目大意

求杨辉三角第 n 行中偶数个数与奇数个数。

题目分析

我们先求第 n 行的奇数个数, 用这一行总数减一下就是偶数个数。

等价于求 i=0n(ni)mod2。把 n,i 拆分成二进制数,二进制每一位记为 nk,ik

根据 Lucas 定理,

(ni)mod2=(nmod2imod2)×(n2i2)mod2

(ni)mod2=1 时, 那么所有的 nk,ik 必定满足 (nkik)=1

  • nk=0 时,有 1 种情况:ik=0
  • nk=1 时,有 2 种情况:ik=0ik=1

等价于 in 的子集,故 n 二进制下若有 k 个 1,答案就为 2k

例题 3Gift

很明显,任意一个 1in1 都有 (abiabi+1)mod2=1。Lucas 显然了。

根据例题 2 的分析,等价于每一个 abi+1 都是 abi 的子集,根据题目条件,还要有 abi+1abi

在值域上开 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;
}

例题 4P4345

根据 Lucas 定理:

(n0)+(n1)++(nk)

=(np0)×(nmodp0)+(np1p)×(nmodp1modp)++(npkp)×(nmodpkmodp)

容易发现 (np0p)(npp1p) 是相同的,(nppp)(np2×p1p) 也是相同的,依次类推。所以可以对式子进行继续化简,提出相同的公因式。令 tj=i=0j(nmodpi),则有:

=(np0)×tp1+(np1)×tp1++(npkp1)×tp1+(npkp)×tkmodp

=tp1×[(np0)+(np1)++(npkp1)]+(npkp)×tkmodp

中括号那一堆和最开始求的东西形式一样,可以进行递归处理。复杂度 O(logpn)

posted @   Otue  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示