杂题记录
2023.4.27 下午 LZY 讲题
ICPC2022 Shenyang - G
题意
给定 \(n\) 个点的两颗树 \(T_1,T_2\)。\(q\) 次询问 \((a,b)\),求 \(\max\limits_x\{d_1(a,x)+d_2(x,b)\}\)。
\(n\leq10^5,q\leq5\times10^5\),提交地址 https://codeforces.com/gym/104160/problem/G。
分析
考虑若给定 \(a\),询问 \(b\),求 \(\max\limits_x\{d_1(a,x)+d_2(x,b)\}\)。考虑在 \(T_2\) 的每个节点 \(x\) 上挂上一个附属节点 \(x^\prime\),边权 \(d_1(a,x)\)。则在 \(T_2^\prime\) 上,\(d(b,x^\prime)=d_1(a,x)+d_2(x,b)\)。先求一遍直径,显然直接分别从两个端点算一遍取 \(\max\) 即可。
考虑将询问离线下来,接下来就是解决 \(a\) 顺着一条边 \((u,v,w)\) 移动的贡献,显然对于 \(v\) 的子树附属边权 \(+w\),非 \(v\) 子树附属边权 \(-w\)。考虑用线段树维护直径,线段树上的区间 \([l,r]\) 表示在 \(T_1\) 上 dfn 序区间 \([l,r]\) 对应到 \(T_2^\prime\) 的直径。在 \(T_1\) 上面 dfs
一遍,顺便处理询问,复杂度 \(\mathcal O(n\log n+q)\)。
ICPC2022 Nanjing - J
题意
给定一张 \(n\) 个点的无向图,每个点有个属性 \(a_i\),两个点 \((i,j)\) 之间右边当且仅当,\(|i-j|=|a_i-a_j|\)。求这张图是否存在完美匹配。
\(n \le 10^5\),提交地址 https://codeforces.com/gym/104128/problem/J。
分析
先说句废话,如果 \(n\) 为奇数,显然没有完美匹配。
看到绝对值,肯定是直接拆看一下有什么结论,上面的条件等价于 \(i+a_i=j+a_j\) 或 \(i-a_i=j-a_j\)。所有可以将问题强化(化简)成:每个点给定两个属性 \((a_i,b_i)\),若 \(a_i=a_j\) 或 \(b_i=b_j\) 就连边。也就是说可以构造一个二分图,其中左部点 \(a_i\) 像右部点 \(b_i\) 连边 \((a_i,b_i,i)\),有公共点的两条边就在原图上右边。
不难发现不同连通块之间相互独立,所以可以抽出一个连通块单独考虑。如果边数为奇数,显然不存在完美匹配。先建出一颗 dfs
生成树,从下往上考虑,对于当前节点 \(u\),考虑所有还未被匹配的儿子边和以它为上端点的返祖边,若边数为奇数就加入父边。这些边两两随便匹配即可。
2023.4.28 容斥相关杂题
[HAOI2018]染色
题意
在长为 \(n\) 的数组上染上 \(m\) 种颜色,若恰好有 \(k\) 种颜色每种出现 \(S\) 次,就对答案贡献 \(w_k\)。求在所有染色方案中贡献和。
\(n\leq10^7,m\leq10^5,S\leq150\),提交地址 https://www.luogu.com.cn/problem/P4491。
分析
恰好 \(k\) 种颜色可能不太好算,先将限制改为至少 \(k\) 种。考虑可以先钦定其中的 \(k\) 种颜色出现 \(S\) 次,剩下的随便选,列出式子 \(g(k)=\dbinom{m}{k}\dfrac{n!}{(S!)^k(n-kS)!}(n-kS)^{m-k}\)。不难发现,\(k\) 最多 \(L=\min(\dfrac{n}{S},m)\)。
显然,这样计算将会算重大量的情况。准确来讲,对于恰好选中 \(k\) 种颜色,它都会被 \(g(k),g(k+1),\dots,g(L)\) 算重。手搓小样例,就可以得出恰好 \(k\) 种颜色的方案数与至少 \(k\) 种颜色方案数之间极其优美的联系:
组合意义就是在乱排的颜色中,有 \(i-k\) 种恰好出现 \(S\) 次,从恰好出现的 \(i\) 种颜色中组合数选出 \(g\) 中被钦定的 \(k\) 种颜色。
于是考虑二项式反演得到:
将这个式子化简,拆开组合数就有:
稍微移一下项得:
立马识别出差卷积形式,设 \(A(i)=\dfrac{(-1)^i}{i!},B(i)=g(i)i!\),就有:
答案直接是 \(\sum_{i=0}^Lf(i)i!w_i\),复杂度 \(\mathcal O(n+L\log L)\)。
Code
提交记录:https://www.luogu.com.cn/record/109077389。
[NOI Online #2 提高组]游戏
题意
有一棵 \(2m\) 个点的树,其中 \(m\) 个白点,\(m\) 个黑点。若第 \(i\) 个白点和第 \(p_i\) 个黑点有祖先关系,则成为一个好事件。记 \(g(k)\) 为恰好 \(k\) 个好事件的排列 \(\{p_n\}\) 的数量。对于 \(k=0,1,\dots,m\) 输出 \(g(k)\bmod 998244353\)。
\(m\leq2500\),提交地址 https://www.luogu.com.cn/problem/P6478。
分析
同样先去掉恰好这个限制,改为至少 \(k\) 个。这样就能设计出 dp
,设 \(f_{u,i}\) 表示以 \(u\) 为根的子树中,有至少 \(i\) 个好事件的方案数。考虑将转移分为两步:
- 先考虑子树的转移:\(f^\prime_{u,i}=\sum_{j=0}^if_{u,j}f_{v,i-j}\)。使用常规子树大小优化复杂度为 \(\mathcal O(n^2)\)。
- 考虑根节点对于子树的贡献,不妨设 \(u\) 为黑点,设 \(s_u\) 为 \(u\) 子树中白点数量,则有:\(f_{u,i}(s_u-i)\to f_{u,i+1}\)。考虑现在算出了
考虑如何将至少 \(k\) 个好事件转换成恰好 \(k\) 个:考虑对于 \(g_k\) 从 \(f_i(i>k)\) 转移,先钦定 \(k\) 对点恰好匹配,剩下的放任不管,于是就有 \(g_k=\sum_{i=k}^m\dbinom{i}{k}f_i\)。
接下来的思路就很明显了,直接二项式反演就有 \(f_k=\sum_{i=k}^m(-1)^{i-k}\dbinom{i}{k}g_i\)。由于 \(m\) 很小,就不需要 NTT
优化了。
总复杂度 \(\mathcal O(n^2)\)。
code
提交记录:https://www.luogu.com.cn/record/109093097。
2023.4.30 线性基相关习题
[SCOI2016]幸运数字
题意
给定一棵 \(n\) 个点的树,每个点有一个权值 \(a_i\)。\(m\) 次询问 u v
,求 \(u\) 到 \(v\) 路径上点权组成的集合的异或最大值。
\(n\le2\times10^4,m\le2\times10^5,a_i\le2^{60}\),提交地址 https://www.luogu.com.cn/problem/P3292。
分析
考虑的要求异或最大值,最简单直接的想法就是构造对应的线性基,但复杂度显然不对。
先简化问题,假设询问的 u v
在一条以 \(1\) 为根的路径上怎么做:不妨假设 \(dep_u<dep_v\),考虑一个简单的贪心,在构造线性基的过程中尽量把深度大的往下放,最后查询答案的时候只取 \(dep_i \ge dep_u\) 的元素。这样的贪心策略显然和直接在 \(u\) 到 \(v\) 的路径上构造线性基显然使等价的。
这启示我们先构造对应的 \(1\) 到节点 \(u\) 的线性基,设为 \(p_u\)。但如果询问不是这样的呢?设 \(L=\text{LCA}(x,y)\),实际上要求的就是合并 \(p_u\),\(p_v\) 深度大于 \(L\) 的部分,所以我们考虑在询问时按照贪心策略暴力合并两个线性基在求答案就行了。
时间复杂度 \(\mathcal O(n\log^2 V)\)。
code
提交记录:https://www.luogu.com.cn/record/109245310。
[WC2011]最大 XOR 和路径
题意
给定一张 \(n\) 个点 \(m\) 条边的无向连通图,求 \(1\) 到 \(n\) 所有路径中边权异或和最大值。
\(n\le5\times10^4,m\le10^5,w_i\le10^{18}\),提交地址 https://www.luogu.com.cn/problem/P4151。
分析
一条由 \(1\) 到 \(n\) 的路径可以被简化成若干个环和链的组合,因为环中和链重合的部分边权异或相互抵消,所以可以在一条正常的路径中通过补全的方式达到这种效果。
如果我们进一步在图上建出对应的以 \(1\) 为根的 dfs
树,那么就可以将这若干条链认为是树上从 \(1\) 到 \(n\) 的树链,在加上若干个由环。这启示我们将所有环插入一个线性基,相当于在 \(ans=dis_x\) 的初值下求和线性基若干个元素异或起来的最大值,直接贪心法就可以了。
时间复杂度 \(\mathcal O(n+m\log V)\)。
code
提交记录:https://www.luogu.com.cn/record/109247979。
2023.5.2 多项式计数相关杂题
[MtOI2018]情侣?给我烧了!
题意
\(n\) 排座位,每排 \(2\) 个座位。定义一对情侣是和睦的当且仅当两人坐在同一排座位上。问 \(n\) 对情侣中恰好 \(k\) 对和睦的方案数。
弱化版:\(T,n\le1000\)。提交地址 https://www.luogu.com.cn/problem/P4921。
加强版:\(T\le2\times10^5,n\le5\times10^6\)。提交地址 https://www.luogu.com.cn/problem/P4931。
分析
首先考虑设 \(D_{n}\) 表示 \(n\) 对情侣错排的方案数。显然答案可以写成:\(Ans_k=\dbinom{n}{k}^2D_{n-k}2^kk!\)。组合意义是从 \(n\) 对中选择 \(k\) 对和睦的,选在他们坐的 \(k\) 排,这 \(k\) 对中:顺序可以换,两人的位置可以交换。问题在于足够快的求 \(\{D_n\}\)。
显然 \(\sum_{k=0}^nAns_k\) 为总方案数,即 \((2n)!\)。所以有 \(\sum_{k=0}^n\dbinom{n}{k}^2D_{n-k}2^kk!=(2n)!\),对式子做变换就有:
识别出卷积形式,考虑设 \(D(n)\) 为 \(\dfrac{D_n}{n!^2}\) 的生成函数,这个式子可以被写成:
前面的转换属于经典 EGF 结论,证明如下:
证明
考虑使用麦克劳林公式,设 $f(x)=e^x$,有:$$e^{2x}=\sum\limits_i\dfrac{f^{(i)}(0)}{i!}(2x)^i=\sum\limits_i\dfrac{(2x)^i}{i!}=\sum\limits_i\dfrac{2^i}{i!}x^i$$ 证毕。后面那玩意假设你足够熟悉广义二项式定理的话,那也可以轻松得出:
证明
先定义实数域上的组合数 $\dbinom{n}{k}=\dfrac{n^\underline{k}}{k!}$,其中 $n\in\mathbb R,k\in\mathbb N$。所以有: $$\begin{aligned}(1-4x)^{-\frac{1}{2}}&=\sum\limits_k\dbinom{n}{k}(-4x)^k\\&=\sum\limits_k\dfrac{(-\frac{1}{2})^{\underline{k}}}{k!}(-4x)^k\\&=\sum\limits_k4^k\dfrac{(\frac{1}{2})^\bar{k}}{k!}x^k\\&=\sum\limits_k4^k\dfrac{(\frac{1}{2})^{2k}(2k)!}{k!^2}x^k\\&=\sum\limits_k\dfrac{(2k)!}{k!^2}x^k\end{aligned}$$ 证毕。所以我们推导出了:
考虑对 \(D(x)\) 求导,有:
考虑将 \(D(x)\) 带回去有:
于是有:
有求导能得出两个显然结论:
于是由上面几个式子有:
移一下项就有:
递推 \(\{D_n\}\),预处理组合数,快速幂算次方,复杂度 \(O(N+T\log N)\)。
code
提交记录:https://www.luogu.com.cn/record/109369647。
[TJOI2015]概率论
题意
求点数为 \(n\) 的不同二叉树叶子数的期望。
\(n\le10^9\)。提交地址 https://www.luogu.com.cn/problem/P3978。
分析
考虑设 \(f_n\) 为点数为 \(n\) 的不同二叉树数量,\(g_n\) 为点数为 \(n\) 的二叉树叶子数之和,即答案。考虑我们要求的答案就是 \(\dfrac{g_n}{f_n}\)。
我们试图寻找两者之间的联系:考虑一棵点数为 \(n\) 的二叉树的每一个叶子都能从唯一的一颗点数 \(n-1\) 的二叉树加上一个点得到。
也就是说我们可以将问题转换成:对于一棵 \(n-1\) 个点的二叉树,有多少种挂叶子的方式?这个问题很简单,考虑你在最初一个节点时有 \(2\) 种挂叶子的方式,而每一次怎加一个节点都会占用一个位置而新产生两个,所以 \(n-1\) 个节点的二叉树有 \(n\) 种不同挂叶子的方式。
于是我们得到了 \(g_n=nf_{n-1}\),至于 \(f_n\) 的计算是经典卡特兰数结论,\(f_n=C_n=\dfrac{\binom{2n}{n}}{n+1}\),那么答案就是 \(\dfrac{n(n+1)}{2(2n-1)}\)。复杂度 \(\mathcal O(1)\)。
code
提交记录:https://www.luogu.com.cn/record/109397415。
2023.5.2 高斯消元相关杂题
CF832E Vasya and Shifts
题意
给定 \(n\) 个字符串,每个字符串最多用 \(4\) 次,询问 \(q\) 次字符串 \(S\),输出在 \(\bmod5\) 意义下,用它们凑出 \(S\) 的方案数。
\(n\le500,q\le300\)。提交地址 https://www.luogu.com.cn/problem/CF832E。
分析
这题不难设方程,假设 \(x_i\) 表示第 \(i\) 个字符串用了几个,\(a_{i,j}\) 表示对第 \(i\) 个字符串,第 \(j\) 位对应的字符在 \(5\) 进制下对应的权值,就有:
发现这是高斯消元,方案数的统计就直接是 \(5^{n-cur+1}\),其中 \(cur\) 为本质不同方程数,即线性不相关的方程数。无解很好判,不讲。但是直接暴力做的复杂度是 \(\mathcal O(qn^3)\),这显然过不去。
我们发现我们做了很多无用功,系数矩阵进行了 \(q\) 次消元,而实际上只需要消元 \(1\) 次就够了。所以我们考虑把所有答案都扔到数组中同意进行消元,判无解单次复杂度 \(\mathcal O(n)\),所以总复杂度 \(\mathcal O((n+q)n^2+qn)\)。
code
提交记录:https://codeforces.com/contest/832/submission/204207377。
2023.5.4 组合计数相关杂题
CF1765C Card Guessing
题意
一个 \(4\) 种花色的牌堆,每种花色 \(n\) 张,每次抽牌前会猜测下一张牌,具体规则如下:考虑第 \(i\) 张牌前 \(\min(k,i-1)\) 张牌,选择其中抽出数量最少的花色集合并从中随机选择一种花色进行猜测。求对于所有不同排列猜中的期望。
提交地址:https://www.luogu.com.cn/problem/CF1765C。
分析
根据期望的线性性,可以将 \(E\) 转换为 \(\sum P\)。
假设第 \(i\) 次猜测的已知卡片数量为 \(c=\min(i-1,k)\)。四种花色分别是 \(c_1,\dots,c_4\),满足 \(c=\sum c_i\)。不同的排列数即:
考虑设 \(p=\min c_i\),显然会随机选择其中一个,推一下式子就有:
组合意义就是猜出下一个式子的概率,拆开组合数:
不难发现如果枚举一个 \(p\),那么 \(\dfrac{c!(4n-c-1)!(n-p)!}{(n-p-1)!}\) 都是常数,另外的部分考虑用背包实现转移,期间要保证存在最小值 \(p\)。
code
提交记录:https://codeforces.com/contest/1765/submission/204446822。
2023.7.24 日 pb 动态规划专题
CF1608F MEX counting
/bx /bx /bx p_b_p_b!
题意
给定 \(n\),\(k\) 和序列 \(\{b_n\}\);求有多少序列 \(\{a_n\}\) 满足 \(\forall i \in [1, n]\):
- \(a_i \in [0, n]\);
- \(|\operatorname{MEX}(a_1, a_2, \dots, a_i) - b_i| \le k\)。
答案对 \(998244353\) 取模。
\(n \le 2000, k \le 50\),提交地址:https://www.luogu.com.cn/problem/CF1608F。
分析
首先分析一下 \(\operatorname{MEX}\) 的性质,令 \(mex_i = \operatorname{MEX}(a_1, a_2, \dots, a_n)\),显然一个合法的 \(\{mex_n\}\) 序列在坐标轴上成阶梯状(单调不减),为了简化题意,我们不妨先考虑 \(k = 0\) 时的做法。
若 \(k = 0\)
显然对于任意的 \(i\),有:\(mex_i = b_i\),所以我们可以对于点 \(i\) 分析出来两个限制:
- \(\forall j \in [1, i],a_j \not = b_i\);
- \(\forall x \in [0, b_i)\),\(x\) 在 \(a_1, a_2, \dots, a_i\) 中出现过。
第一个限制是好处理的,第二个比较难办。我们可以进一步将这个限制抽象成:\(\forall x \in [0, b_i)\),\(x\) 在 \(a_{1 \sim i}\) 这个前缀中至少出现一次。至少就启示我们考虑容斥,显然至少在前缀中出现一次等价于可以出现在任意位置减去只能出现在后缀。
依据这个做法我们可以设计 dp 方程:\(f_{i,j}\) 表示从后往前考虑到坐标轴折线上的第 \(i\) 个点,当前钦定 \(j\) 种值只能出现在后缀中的方案数。转移分为两种:
- 在平行段:显然因为每种值在后缀中一定能出现,所以只用考虑只能在 \(i\) 之后的后缀中出现的值,显然只有这 \(j\) 中不行,方案数 \(n - j + 1\);
- 在下降段:直接枚举当前这种值是否钦定,乘上容斥系数即可,注意特殊的,当考虑到拐点的时候这个值由于第一种限制,一定只能在后缀中出现。
复杂度 \(\mathcal O(n^2)\)。
若 \(k \ge 0\)
现在的 \(mex_i\) 的可能取值为一段区间 \([\max(0, b_i - k),\min(n, b_i + k)]\),实际上转移的原理不变,但是要对状态做一些更改。
设 \(f_{i,j,k}\) 表示从后往前考虑到第 \(i\) 个位置,钦定 \(mex_i = j\),钦定 \(k\) 个值只在后缀中出现的方案数。第一种转移不变,只需要在每个位置新增第二种转移即可,具体见代码。
复杂度 \(\mathcal O(n^2k)\)。
这种做法常数较小,无需卡常。
Code
提交记录:https://codeforces.com/contest/1608/submission/215325752。
2023.9.27 随机杂题
[ARC141D] Non-divisible Set
题意
给定大小为 \(n\) 的不可重整数集合 \(S\),满足 \(\forall x \in S : x \in [1, 2m]\)。
求对于每个 \(x \in S\),是否存在集合 \(T\) 满足 \(T \subseteq S, |T| = m, x \in T\),且 \(\forall x, y \in T : x \not \mid y\)。
\(1 \le m \le n \le 2m, m \le 3 \times 10^5\),提交地址:https://atcoder.jp/contests/arc141/tasks/arc141_d。
分析
先考虑若 \(S = [1, 2m]\) 怎么做。
打表发现对于一个大于 \(m\) 的奇数,一定要出现在 \(T\) 中。我们不妨考虑将奇数提取出来,依据它们分组。考虑每个偶数都可以写成 \(2^kx\),其中 \(x\) 是一个奇数,依据 \(x\) 分组,例如 \(m = 5\) 的表格如下:
\(1\) | \(3\) | \(5\) | \(7\) | \(9\) |
---|---|---|---|---|
\(2\) | \(6\) | \(10\) | ||
\(4\) | ||||
\(8\) |
有一个极强的限制是 \(|T| = m\),不难发现此时恰分成 \(m\) 组。进一步的观察告诉我们同一组中只能选择一个,所以我们的限制变成每个组中恰选一个。
分析一下现在的限制:要求两个组所选的书之间不存在倍数关系。设 \((x, y)\) 表示的数为 \(x2^y\),考虑表格上 \((x, y)\) 和 \((x^\prime,y^\prime)\) 之间有倍数关系的条件(不妨设 \(x < x^\prime\)):\(x \mid x^\prime \land y \le y^\prime\)。
我们不能控制第一部分,但是我们能控制第二部分,所以若数 \(x\) 选择了 \(y\),它所有的倍数选择的 \(y^\prime\) 就必须小于它。这个递推关系显然是线性无后效性的。所以正反个做一遍 dp 就能解决这一部分,复杂度 \(\mathcal O(m\ln m)\)。
考虑如果 \(S \subseteq [1, 2m]\) 怎么办,我们只需要在递推的时候找到第一个在 \(S\) 中的就可以了,复杂度 \(\mathcal O(m\ln m + n)\)。
Code
提交记录:https://atcoder.jp/contests/arc141/submissions/45969420。
9.22 NTF 集训队讲题
https://www.cnblogs.com/BingAD/articles/17755531.html。
11.28 李超线段树选题
P4069 [SDOI2016] 游戏
题意
给定一颗 \(n\) 个节点的树,每个节点有一个初始数字 \(123456789123456789\),\(m\) 此操作:
1 s t k b
,对每个结点 \(u \in \operatorname{Path}(s, t)\),在节点 \(u\) 上插入数字 \(k\operatorname{dis}(u, s) + b\);2 s t
,查询 \(s\) 到 \(t\) 的路径上数字的最小值。
\(n, m \le 10^5\),提交地址:https://www.luogu.com.cn/problem/P4069。
分析
考虑看到距离先拆成深度,即变成 \(k \times (dep_s + dep_u - 2 \times dep_{\operatorname{lca}(s, u)}) + b\) 的形式,不难想到将将路径拆成上下两部分:
上,式子可以化成:
下,同理(记 \(l\) 为 \(\operatorname{lca}(s, t)\)):
两个都是关于 \(dep\) 的一次函数,我们考虑维护路径信息,于是进行树剖,不难发现在一条重链上,\(dep\) 是单增的,所以李超线段树可以直接使用,直接维护就好了。
时间复杂度 \(\mathcal O(n\log^2 n)\)。
Code
提交记录:https://www.luogu.com.cn/record/137260633。