20250909
选择排序
对一个排列进行选择排序,要求第 \(i\) 轮排序的交换次数为 \(c_i\),求满足要求的初始排列方案数。\(1 \le n \le 10^6\)。
选择排序每一轮会把剩下的所有前缀最小值拎出来右移,然后把移出去的那个删掉。每一轮的交换次数为当前不是全局最小值的前缀最小值数量。
发现在 \(i\) 第 \(j\) 轮参与右移之后,直到第 \(i\) 轮都会参与右移。
考虑倒着还原,已经确定第 \(i + 1\) 轮参与右移的有 \(c_{i + 1} + 1\) 个,第 \(i\) 轮除了 \(i\) 还有 \(c_i\) 个在右移,它们应当在 \(c_{i + 1} + 1\) 个中任选,每一种选法对应一种第 \(i\) 轮前的状态。
答案是:
Help Yourself
https://www.luogu.com.cn/problem/P6144
使用第二类斯特林数进行普通幂转下降幂。
于是单次 \(O(k)\) 单点修改 \(x \leftarrow x + 1\)。
按照左端点从小到大排序,使用线段树维护以每个右端点结尾时 \(\sum \binom{x}{i}\) 的和。
转移讨论之前已选择线段的最大右端点位置在 \([1, l), (l, r), (r, 2n]\) 哪一个即可。
度度熊与运算式 2
https://acm.hdu.edu.cn/showproblem.php?pid=6679
简单题。下文 \(n \leftarrow n + 1\),\(k = \lfloor \log_2 n \rfloor + 1\)。
第一问显然取到 \(n\)。那么所求为:有多少种方案,把 \(+\) 改成 \(\oplus\),使得不发生进位。
对于可以填 \(\oplus\) 的位置,\(f(S) = \sum_{T \subset S}f(T)\),直接子集枚举是 \(O(3^k)\) 的。
对每一个位置 \(S\) 和每个 \(i\),记录所有 \(T \subseteq S\) 且 \(S\) 和 \(T\) 在比 \(i\) 高的位上相同的 \(f(T)\) 的和。
f[0] = 1;
for (int i = 0; i <= 20; ++i) g[0][i] = 1;
for (int S = 1; S <= n; ++S) {
for (int i = 0; i <= 20; ++i) {
g[S][i] = i ? g[S][i - 1] : 0;
if (S >> i & 1) Fplus(g[S][i], g[S ^ 1 << i][i]);
}
f[S] = bn[S] ? 0 : g[S][20];
for (int i = 0; i <= 20; ++i) Fplus(g[S][i], f[S]);
}
Poborcy podatkowi
https://www.luogu.com.cn/problem/P9047
DP,然后随机化 shuffle 一下,则当前不会离 \(0\) 偏离太多。一个随机排列的 LIS 的期望长度为 \(\sqrt n\)。

浙公网安备 33010602011771号