杂题

CF2222D

以下默认 \(j>i\).

\(b_i=\sum_{k=1}^{i-1}a_k\),则逆序对 \((i,j)\) 的贡献为 \(b_j-b_i\).

考虑最大化贡献,即对于任意 \(b_j>b_i\)\(p_j<p_i\)(算进贡献),对于任意 \(b_j<b_i\)\(p_j>p_i\)(不算贡献),发现这个上限是可以取到的. 构造方法为对于 \(b\) 中从小到大排名为 \(i\)\(p\) 赋为 \(n-i+1\).

CF2218G

\(c_i=\sum_{j=1}^n[b_j\leq i]\).

\(b_{i-1}\geq b_i\)\(b_{i+1}\geq b_i\)\(b_i\neq 0\),答案为 \(0\),因为第 \(i\) 个人不可能坐下.

否则,若 \(b_i=0\),则 \(a_i\) 只能取 \(0\).

否则,若 \(b_{i-1}<b_i-1\)\(b_{i+1}<b_i-1\) 即他的邻居坐下条件已经被提前满足了,则 \(a_i\) 可取 \([c_{b_i-2}+1,c_{b_i-1}]\) 的任意值.

否则,因为邻居会比他晚坐下,所以 \(a_i\) 可取 \([1,c_{b_i-1}]\) 的任意值.

答案为每个位置的可能值之积.

CF2211C2

题目描述等价于:\([a_1,\dots,a_k]\)\([b_1,\dots,b_k]\) 的重排,且 \(\forall\,i\in[1,n-k]\)\(a_i=b_i\land a_{i+k}=b_{i+k}\)\(a_i=a_{i+k}\land b_i=b_{i+k}\).

\(S_p=\bigl\{(a_i,b_i)\;\bigl|\;i\equiv p\pmod k\bigr\}\),于是上述第二个条件等价于:\(\forall\;p\in[0,k)\)\(S\) 中相邻两个有序对 \((a_i,b_i)\)\((a_{i+1},b_{i+1})\) 满足 \(a_i=b_i\land a_{i+1}=b_{i+1}\)\(a_i=a_{i+1}\land b_i=b_{i+1}\).

对于每个 \(p\),若 \(b_i\) 处不是 \(-1\)\(a_i\neq b_i\),那么整个 \(a\) 都必须是相等的,整个 \(b\) 都必须是相等的.

对于每个 \(p\),若 \(b_i\) 处不是 \(-1\)\(a_i=b_i\),对于每处 \(i\) 都必须满足 \(a_i=b_i\).

对于每个 \(p\),若 \(b_i\) 全都是 \(-1\),需要构造一个 \(b\) 满足上述两种情况之一. 当 \(a\) 中有不同元素时,只能是第二种,即 \(a_i=b_i\);若 \(a\) 中全都是同一个数,两种都能选,但此时第二种自由度更高,可以给 \(b_1\) 赋任意值,后面的都需要和 \(b_1\) 相等.

现在需要尽可能满足 \([a_1,\dots,a_k]\)\([b_1,\dots,b_k]\) 的重排. 因为 \([b_1,\dots,b_k]\) 映射到 \(p\in[0,k)\)\(S_p\) 中的 \(b_1\),所以如果 \(b_i\) 仍未确定,那么它可以取任意值. 因此我们检查每个数在 \(a\) 的前 \(k\) 个中和在 \(b\) 的前 \(k\) 个中出现的次数,如果在 \(b\) 中的不大于在 \(a\) 中的就可行.

于是我们得出答案.

CF2208D1

令输入的矩阵为 \(g\).

有边 \(u\to v\) 当且仅当 \(g_{u,v}=1\),且 \(\nexists\,k\neq u\land k\neq v,\;g_{u,k}=g_{k,v}=1\).

最后需要检查边数是否为 \(n-1\)、是否构成树、重新生成矩形后是否与原矩形相等.

CF1427C

\(f_i\) 表示 \(t_i\) 时刻位于 \((x_i,y_i)\) 的最大总价值,则转移式为

\[f_i=\max_{\substack{j<i\\|x_i-x_j|+|y_i-y_j|\leq t_i-t_j}}f_j+1 \]

\(t_i\) 时刻不可能位于 \((x_i,y_i)\),令 \(f_i=+\infty\).

\(x_0=y_0=1\)\(t_0=0\)\(f_0=0\),这就是初始状态.

最终答案为 \(f_n\).

这样做的时间复杂度为 \(O(n^2)\). \(|x_i-x_j|+|y_i-y_j|\leq 2r\),所以当 \(t_i-t_j\geq 2r\) 时,\(|x_i-x_j|+|y_i-y_j|\leq t_i-t_j\) 必定成立. 又因为 \(t_i\) 是严格单调递增的,所以维护 \(f_j\) 的前缀最大值,对于 \(t_i-t_j\geq 2r\) 的部分直接通过前缀最大值转移,剩余部分直接枚举. 因为 \(t_i\neq t_{i+1}\),所以满足 \(t_i-t_j<2r\)\(j\) 不超过 \(2r-1\) 个.

时间复杂度为 \(O(nr)\).

QOJ9539

题意为有多少种方案,选出一个联通块,包含 \(u\sim v\) 路径上的任意一点.

\(u\)\(v\)\(\operatorname{LCA}\)\(L\),该联通块为与 \(u\sim v\) 路径的交点集合中深度最浅的节点为 \(r\),则:

\(r\neq L\),则联通块内的元素都属于 \(r\) 的子树. 否则,\(r\) 一定会更浅.

\(r=L\),则联通块可以以 \(L\) 为界被拆为两个部分:\(L\) 的子树的一部分,\(L\) 的子树外节点.

\(f_u\) 表示 \(u\) 子树内选联通块,包含 \(u\) 的方案数;\(g_u\) 表示 \(u\) 子树外选联通块,包含 \(u\) 的方案数.

则对于每个询问,答案为:

\[f_L\cdot g_L+\sum_{\substack{x\in u\sim v\\x\neq L}}f_x \]

维护 \(f\) 的树上前缀和,即 \(q_u=q_{\operatorname{fa}_u}+f_u\),则式子变为

\[f_L\cdot g_L+q_u+q_v-2q_L \]

只要处理出了 \(f\)\(g\),就可以 \(O(1)\) 回答单次询问.

接下来考虑计算 \(f\). 对于每个 \(u\)\(f_u\) 的方案中一定包含 \(u\),同时包含若干个子节点的方案. 对于每个子节点 \(v\),可以不选,或者选,方案数和为 \(1+f_v\),于是

\[f_u=\prod_{v\in\operatorname{son}_u}\bigl(1+f_v\bigr) \]

可以 \(O(n)\) 预处理.

考虑计算 \(g\). 初始情况为 \(g_1=1\). 目前已知 \(g_u\)\(v\)\(u\) 的子节点,考虑转移到 \(g_v\). \(u\) 的子树外节点和 \(v\) 的子树外节点的差别为:\(u\)\(u\) 除了 \(v\) 的子节点.

对于 \(g_v\),可以只选 \(v\),有 \(1\) 种方案. 如果向 \(u\) 延伸,则方案可以被分为:\(u\) 的子树外节点,和 \(u\) 除了 \(v\) 的子节点. 对于 \(u\) 的子树外节点,方案数为 \(g_u\);对于 \(u\) 除了 \(v\) 的子节点 \(w\),方案数为 \(1+f_w\).

得出 \(g_v\) 的式子:

\[1+g_u\cdot\prod_{\substack{w\in\operatorname{son}_u\\w\neq v}}\bigl(1+f_w\bigr) \]

对于每个 \(u\),处理出 \(1+f_w\) 的前缀积和后缀积,因为可能存在 \(\bigl(1+f_w\bigr)\equiv 0\pmod{998244353}\),所以不能使用逆元.

最终以 \(O(n+q\log n)\) 的时间复杂度解决本题(每次查询 \(\operatorname{LCA}\) 的时间复杂度为 \(O(\log n)\)).

洛谷P12415

\(f_{i,s}\) 表示前 \(i\) 行放了 \(s\) 个点的方案数. 转移为枚举下一行放多少个点,式子如下:

\[\binom{m}{j}\cdot s^j\cdot f_{i,s}\to f_{i+1,s+j} \]

其中,\(\binom{m}{j}\) 是在第 \(i+1\) 行放 \(j\) 个点的方案数,\(s^j\) 是为每个新放的点找一个父亲的方案数.

枚举根所在行,令其为 \(r\),则初始状态为 \(f_{r,1}=m\),答案为 \(\sum_{s=0}^{nm}f_{n,s}\). 设根在第 \(r\) 行的答案为 \(F_r\),则答案为

\[\sum_{r=1}^nF_r \]

因为转移式系数与 \(i\) 无关,所以第 \(r\) 行开始转移到第 \(n\) 行和第 \(1\) 行转移到第 \(n-r+1\) 行是等价的. 因此我们设初始状态为 \(f_{0,1}=m\),则答案为

\[\sum_{i=1}^n\sum_{j=1}^{nm}f_{i,j} \]

状态数为 \(n^2m\),单次转移是 \(O(m)\) 的,所以总时间复杂度为 \(O(n^2m^2)\).

洛谷P8314

考虑二分答案 \(\operatorname{dis}\). 需要限制社区到最近公园的距离 \(\leq\operatorname{dis}\),求最少要放多少公园. 单调性是显然的,不妨设两个距离 \(x_1<x_2\),若 \(x_1\) 可以成功,\(x_2\) 直接沿用 \(x_1\) 的方案,必然可以成功.

贪心的策略是:对于一个节点 \(u\),如果在 \(u\) 放可以覆盖子树,且在 \(\operatorname{fa}_u\) 放也可以覆盖 \(u\) 的子树,那么一定会在 \(\operatorname{fa}_u\) 或者深度更浅的祖先放. 局部最优的正确性是显然的,因为在祖先放可以覆盖的节点一定不会少于在 \(u\) 放的.

贪心考虑的过程是:自叶子向根,能不放就不放. 检查在父亲放是否能覆盖子树,如果不能就在自己放. 因此从根开始 \(\operatorname{DFS}\),合并所有子树. 合并时,子树之前也可以互相贡献. 因此我们对于每个节点 \(u\) 维护两个值:\(\operatorname{low}_u\) 表示 \(u\) 子树内最近的公园到 \(u\) 的距离(若没有,则设为 \(+\infty\));\(\operatorname{deep}_u\) 表示 \(u\) 子树内未被覆盖的点到 \(u\) 的最大距离(初始为 \(0\),因为 \(u\) 本身就没有被覆盖).

那么,\(\operatorname{deep}_u\) 对应点一定可以被 \(\operatorname{low}_u\) 对应点或 \(u\) 及其祖先覆盖. 如果 \(\operatorname{deep}_u+\operatorname{low}_u>\operatorname{dis}\),则必须由 \(u\) 及其祖先覆盖. 令 \(\operatorname{tofa}_u\) 表示 \(u\)\(\operatorname{fa}_u\) 的边的长度,则当 \(\operatorname{tofa}_u+\operatorname{deep}_u>\operatorname{dis}\) 时,必须在 \(u\) 放一个公园.

接下来是转移细节. 后序遍历整棵树,合并时更新 \(\operatorname{low}_u\)\(\operatorname{deep}_u\). 对于每个儿子 \(v\) 和对应边权 \(w\),转移式如下:

\[\operatorname{low}_u\xleftarrow{\min}\operatorname{low}_v+w \]

\[\operatorname{deep}_u\xleftarrow{\max}\operatorname{deep}_v+w \]

合并完所有儿子后,计算子树之间的覆盖情况. 若 \(\operatorname{low}_u+\operatorname{deep}_u\leq\operatorname{dis}\),则整棵子树的所有节点均已被覆盖,需要更新 \(\operatorname{deep}_u\leftarrow-\infty\).

最后决定是否在 \(\operatorname{u}\) 建公园,即

\[\operatorname{tofa}_u+\operatorname{deep}_u>\operatorname{dis} \]

是否成立. 需要注意的是,在 \(\operatorname{u}\) 建公园后需要更新,即 \(\operatorname{low}_u\leftarrow 0\)\(\operatorname{deep}_u\leftarrow-\infty\).

最终,对于根节点 \(\operatorname{root}\) 需要特殊处理. 因为它没有父亲,所以当 \(\operatorname{deep}_{\operatorname{root}}\neq-\infty\) 时,必须在根建公园.

在计算公园个数时,顺便记录在哪里建了公园. 最终答案中,如果建的公园数量小于 \(k\),任意选择没有建公园的节点即可.

CF2249C

\(f(k)\) 表示从第 \(k\) 位开始到每个位置的连续段数量,返回一个长度为 \(n\) 的序列. 区间 \([l,r]\) 表示从 \(l\) 开始顺时针取到 \(r\),因此 \(l>r\) 是可能的.

首先处理出 \(f(1)\). 接下来,假设已经算出了 \(f(k)\),考虑如何从 \(f(k)\) 转移到 \(f(k+1)\).

不妨对于每个结尾 \(l\) 计算 \(f(k)_l\)\(f(k+1)_l\) 的关系. 这相当于删除开头 \(p_k\).

对于 \(p_k\in(1,n)\) 的情况:

\(p_k\pm 1\)\(p\) 中的出现位置为 \(s\)\(t\),其中从 \(k\) 开始顺时针走会先碰到 \(s\).

\(l\in[k+1,s)\) 时,\(p_k\) 是独立的一个连续段,因此 \(f(k)_l-1\to f(k+1)_l\).

\(l\in[s,t)\) 时,\(p_k\)\(p_k\pm 1\) 中的一个在同一个连续段中,此时删除 \(p_k\) 对连续段数量没有影响,因此 \(f(k)_l\to f(k+1)_l\).

\(l\in[t,k)\) 时,删除 \(p_k\) 会分裂 \(p_k-1\)\(p_k+1\) 所在连续段,因此 \(f(k)_l+1\to f(k+1)_l\).

\(l=k\) 时,\(f(k+1)_l\) 就是整个序列的连续段数量,因此 \(1\to f(k+1)_l\).

对于 \(p_k=1\)\(p_k=n\) 的情况:

\(p_k=1\) 时,设 \(s\) 表示 \(2\)\(k\) 中出现的位置. 当 \(p_k=n\) 时,设 \(s\) 表示 \(n-1\)\(k\) 中出现的位置.

\(l\in[k+1,s)\) 时,同上,\(f(k)_l-1\to f(k+1)_l\).

\(l\in[s,k)\) 时,同上,\(f(k)_l\to f(k+1)_l\).

\(l=k\) 时,同上,\(1\to f(k+1)_l\).

对于一个位置 \(k\),它是好的起始位置等价于 \(f(k)\) 中每个数都小于等于 \(2\),即 \(\max_{l=1}^n f(k)_l\leq 2\). 我们需要一个数据结构,支持区间加和区间求 \(\max\),使用线段树维护.

CF1776F

对于一个度数小于 \(n-1\) 的点 \(u\),将 \(\forall\,v,\;u\to v\) 染色为 \(1\),将其他边染色为 \(2\). 假设从 \(u\) 无法到达的点之一为 \(x\),则只经过颜色为 \(1\) 的边无法到达 \(x\),只经过颜色为 \(2\) 的边无法到达 \(u\),满足题目要求.

对于完全图,任选一个点 \(u\),把所有以它为顶点的边染色为 \(1\),并其中的一条染色为 \(3\),假设颜色为 \(3\) 的那条边连接了 \(u\)\(v\),那么只经过颜色为 \(1\) 的边无法到达 \(v\),只经过颜色为 \(2\) 的边无法到达除了 \(u\)\(v\) 之外的点,只经过颜色为 \(3\) 的边无法到达 \(u\). 同时经过颜色为每两种颜色的边能到达所有点.

CF2249B

首先,如果 \(v\) 中出现了 \(n\),方案数就是 \(0\),因为这要求左右两侧的最大值都不小于 \(n\),这是不可能的.

\(n\)\(p\) 中的出现位置为 \(x\),则当 \(i<x\) 时,\(v_i=\min\left(\max_{1\leq j\leq i}p_j,\,n\right)=\max_{1\leq j\leq i}p_j\),即前缀最大值;当 \(i\geq x\) 时,\(v_i=\min\left(n,\,\max_{i+1\leq j\leq n}p_j\right)=\max_{i+1\leq j\leq n}p_j\),即后缀最大值. 因此 \(v_i\)\([1,x-1]\) 上单调不减,在 \([x,n-1]\) 上单调不增,且 \(v_{x-1}\neq v_x\),因为 \(p\)\([1,x-1]\) 的最大值和 \(p\)\([x+1,n]\) 的最大值一定不同. 对于 \(x=1\)\(x=n\)\(v_{x-1}\)\(v_x\) 不同时存在,此时只需要满足单调性. 对于每一个 \(x\) 统计方案数.

证明可行的 \(x\) 最多有 \(2\) 个:设三个满足条件的位置 \(x_1<x_2<x_3\),因为 \(x_2\) 在中间,所以必有 \(1<x_2<n\),因此 \(v_{x_2-1}\neq v_{x_2}\). 因为 \(x_1\) 可行,所以需要满足 \(v\)\([x_1,n-1]\) 上单调不增,则 \(v_{x_2-1}\geq v_{x_2}\),可得 \(v_{x_2-1}>v_{x_2}\);因为 \(x_3\) 可行,所以需要满足 \(v\)\([1,x_3-1]\) 上单调不减,则 \(v_{x_2-1}\leq v_{x_2}\),与 \(v_{x_2-1}>v_{x_2}\) 矛盾,因此不可能存在 \(3\) 个及以上合法的 \(x\),因此可行的 \(x\) 最多有 \(2\) 个,例如 \(v\) 恒等时,\(1\)\(n\) 均合法(上界可以达到).

对于每一个 \(x\),先考虑它左边的部分,\([v_1,v_2,\dots,v_{x-1}]\). 若 \(v_i>v_{i-1}\),则 \(p_i=v_i\),否则无法更新前缀最大值. 若 \(v_i=v_{i-1}\),则 \(p_i\leq v_i\),否则会更新前缀最大值,可行方案数为不大于 \(v_i\) 的未被使用的数的数量. 对于右边的部分,\([v_x,v_{x+1},\dots,v_{n-1}]\),它代表后缀最大值,将其翻转后就代表前缀最大值,可以用和左边部分一样的方法计算方案数. 需要注意的是,若左边部分和右边部分出现相同的数应当直接方案数为零,因为同一个数不可能同时出现在左右侧.

考虑如何维护不大于 \(v\) 的未被使用的数的数量. 我们将左边部分和翻转后的右边部分使用归并排序中合并两个有序序列的思想合并,得到一个单调不降的序列 \(b\),对于每个 \(b_i\),不大于它的未被选中的数的数量为 \(v_i-i+1\),因为它前面的 \(i-1\) 个数都不大于它(\(\forall\,j<i,\;p_j\leq b_j\leq b_i\)). 需要特殊处理 \(b_i-i+1\) 为负的情况,此时方案数应为 \(0\).

posted on 2026-08-08 18:45  吴一鸣  阅读(16)  评论(0)    收藏  举报

导航