2024.11
P10099 [ROIR 2023 Day 2] 美丽序列
枚举当前点放哪个数,上一个 \(x\) 到 \(i\) 的距离必须不小于 \(x\)。
距离的取值只有 \(1, 2, \cdots, x -1, \ge x\),把每种数的距离压进状态,状态数 \(8!\) 能够接受。
P2993 [FJOI2014] 最短路径树问题
建出最短路图(若 \(d_v = d_u + w\) 则连边 \(u \to v\))。
从 \(1\) 开始 dfs,贪心的按儿子大小遍历。
这样为什么是对的?
对于两条到 \(u\) 路径的 lcp:\(1 \to\cdots i \to j \to \cdots u\) 和 \(1 \to\cdots i \to k \to \cdots u\)。
若 \(j < k\),选第一条路径更优,而在 \(i\) 时一定先遍历 \(j\),再遍历 \(k\),保证了正确性。
后面是点分治板子。submission
P3164 [CQOI2014] 和谐矩阵
不难列出 \(n \times m\) 个 \(n \times m\) 元方程,可以做到 \(O(\frac{(nm)^3}{w})\)。
如果矩阵满秩,一定无解,因为最终可以消成 \(\forall i\in [1, n\times m],\ a_i = 0\) 的形式。
否则把任意一个自由元设为 \(1\) 即可。
P9905 [COCI 2023/2024 #1] AN2DL
二维单调队列板子。
P4796 [BalticOI 2018] 路径
\(f(u, s)\) 表示从 \(u\) 开始,颜色状态为 \(s\) 的方案数,从 \(f(v, s \oplus c_u)\) 转移。
P3165 [CQOI2014] 排序机械臂
平衡树裸题:1. 区间翻转 2. 单点删除 3. 查询子树最小值。
P3172 [CQOI2015] 选数
设 \(g_n\) 表示 gcd 能被 \(n\) 整除的方案数,\(f_k\) 为 gcd 为 \(k\) 的方案数:
选出 \(n\) 个形如 \(ki \in [L, H]\) 等价于选 \(n\) 个 \(i \in \left[\lceil\frac{L}{K}\rceil,\ \lfloor\frac{H}{K}\rfloor\right]\) 满足两两互质。
\(L \gets \lceil\frac{L}{K}\rceil, H \gets \lfloor\frac{H}{K}\rfloor\),最后求:
整除分块,杜教筛求 \(\mu\) 前缀和,复杂度不会。
$1:杜教筛
记 \(S(n) = \sum_{i = 1}^n f(i)\),构造 \(h = g * f\)。
移项:
$2:一个精妙的容斥
对于 \(d > H - L\),不存在两个不同的 \(x, y\) 使得 \(\gcd(x, y) = d\)。
记 \(f_i\) 表示 gcd 恰好为 \(i\),且 \(N\) 个数不全相等的方案数,有 \(f_{i > H-L} = 0\)。
设 \(x = \lfloor\frac{H}{i}\rfloor - \lfloor\frac{L - 1}{i}\rfloor\),那么 \(f_i = (x^N - x) - \sum_{ij \le H - L} f_{ij}\)。
所求即 \(f_1 + [L \ge 1]\)。
P4792 [BalticOI 2018] 火星人的 DNA
双指针板子。下位黄,哪来蓝的。
P10100 [ROIR 2023 Day 2] 石头
对于询问 \((p, k)\),要么 \([p + 1, p + k - 1]\) 被染色,要么 \([p - k + 1, p - 1]\) 被染色。
不妨考虑第一种。
假设起始点为 \(s\),当前左右端点分别为 \(i, j\)。
我们需要循环往复执行一下操作:左移 \(i\) 直至 \(a_{i - 1} > a_{j + 1}\);右移 \(j\) 直至 \(a_{j + 1} > a_{i - 1}\)。
称 \(a_{j + 1}\) 和 \(a_{i - 1}\) 为阈值,左右阈值都是单调上升的。
说的形象一点,设左边的阈值下标集合为 \(A\),右边为 \(B\)(按访问顺序排序):
- \(i \gets A_{k} + 1,\ k \gets k + 1\)。
- \(j \gets B_l - 1,\ l \gets l + 1\)。
\(a_{p + k}\) 是阈值,因为 \(p + k - 1\) 是一个连续段的末尾(连续往一个方向移动)。
左侧最大阈值必须小于 \(a_{p + k}\),否则继续往右移动。
也就是说,\(a_{p + k}\) 大于除 \(s\) 外 \([p, p + k - 1]\) 的最大值。
左边最大阈值必须大于右边除 \(a_{p + k}\) 外的最大阈值,即 \(\max[p, s - 1] > \max[s + 1, s + k - 1]\)。
否则左边比右边先走完。
现在找到了判断某个 \(s\) 合法的条件,开始统计答案。
如果 \(\max[p, p + k - 1] > a_{p + k}\),至多产生 \(1\) 的贡献,判断 \(s\) 为最大值的位置即可。
否则只需考虑 \(\max[p, s - 1] > \max[s + 1, s + k - 1]\)。
从右往左枚举 \(s\),相当于往右式加一个元素,左式减一个元素,这是有单调性的,可以二分。
P10101 [ROIR 2023 Day 2] 一个普通的字符串问题
题意:求长度为 \(2\) 的子串集合与 \(s\) 相同的字符串 \(t\) 数量,\(\sum = \{a, b, c\}\)。
\(s_i\) 向 \(s_{i + 1}\) 连有向边,一条边对应一个长度为 \(2\) 的子串。
所求 \(t\) 的数量即图中欧拉路径数量(重边视为相同)。
枚举起点终点,终点向起点连边,转化为BEST定理求欧拉回路,最后除以每条重边的阶乘。
(新加的边是和原来重边区分的)
QOJ 5981
原问题转化为,求最小的花费,确定 \(x\) 与每个 \(a_i\) 的大小关系。
如果 \(x > a_i\),那么对于 \([1, i)\) 都已经确定关系,只需解决 \((i, n]\) 的子问题。
这启发我们进行区间DP,\(f_{l, r}\) 表示确定这段区间所有关系的最小花费:
为什么要取max?因为我们考虑的是最坏情况,\(x\) 与 \(a_i\) 关系不确定。
答案很小,容易构造出一个上界 \(9\log n\)。
交换值域定义域,\(f(l, v)\) 表示左端点为 \(l\) 花费至多 \(v\) 的代价能处理的最大右端点。
考虑在 \(i\) 决策的两种情况:
- \(x > a_i\),此时左边完全不需考虑,\(f(i + 1, v - w_i)\) 贡献给 \(f(l, v)\)。
- \(x < a_i\),此时右边完全不考虑,可以延伸到 \(n\),但是左边必须用剩余 \(v - w_i\) 覆盖到 \(i - 1\)。
因此 \(i\) 的贡献为,在 \(f(l, v - w_i) \ge i - 1\) 的条件下,\(f(i + 1, v - w_i)\) 和 \(n\) 取min。
树状数组优化转移,细节较多,且时空复杂度很劣,过不了原题。
$正解
把上面朴素方程的 \(l, r\) 改成开区间,即:
初始化 \(f_{i, i + 1} = 0\),结果为 \(f_{0, n + 1}\)。
设 \(L(i, v)\) 表示最小的 \(l\) 满足 \(f_{l, i} \le v\),\(R(i, v)\) 表示最大的 \(r\) 满足 \(f_{i, r} \le v\)。
枚举 \(v\),考虑在 \(i\) 处合并。
令 \(l = L(i, v - w_i),\ r = R(i, v - w_i)\),那么 \(R(l, v) \gets r,\ L(r, v) \gets l\),<--
表示更新。
上述转移只能更新到边界,因此还需 \(L(i, v) \gets L(i + 1, v),\ R(i, v) \gets R(i - 1, v)\)。
最多访问到 \(L(i, v - 9)\),滚动数组优化空间。
沙漠点列(link)
题意:给出一个沙漠,删去其中的 \(k\) 条边,求能分成的连通块数量最大值。
如果存在割边,则删割边。
否则需要断环来创造割边,断开一个长度为 \(n\) 的环产生 \(n - 1\) 条割边。
tarjan找环,贪心的按环长排序。
QOJ 5173
肯定是单方向从 \(l\) 到 \(r\),因为往回走不优。
\(r - l\) 走的步数是没法减的,现在要尽可能少染色。
显然有染色上界 \(r - l\),即 \((l, r]\) 染成 \(a_l\)。
如果某个 \(a_i = a_{i + 1}\),原先给 \(a_i\) 染色的一步让 \(a_{i - 1}\) 染成 \(a_i\),这样就能在 \(a_{i + 1}\) 省下一步。
推广一下,如果存在 \(a_j = a_i\),同样可以通过类似操作省下一步。
问题转化为,选出最多的二元组 \((i, j)\) 满足 \(l \le i < j \le r\land a_i = a_j\),且相邻二元组不相交(端点可以重合)。
假设当前在 \(p\),走到一个 \(i \ge p\) 且 \(j\) 最小的一个 \(j\) 是最优的,设这个位置为 \(fa_p\)。
问题转化为,从 \(l\) 开始跳父亲,在 \(r\) 范围内最多跳多少步,显然是可以倍增的。
据说倍增卡常,对 \(r\) 进行扫描线,并查集维护每个 \(l\) 对应 \(\le r\) 的最大祖先。
并查集必须按秩合并路径压缩都加上复杂度才是 \(\alpha\) 的。
QOJ 7855
点分树维护路径问题。
对于每一个分治中心,只有最小和次小的两个 \(d_i\)(到分治中心的距离)有用,产生 \(d_i + d_j\) 的贡献。
如果 \(i, j\) 在一颗子树里面,真正的答案一定小于 \(d_i + d_j\),不会产生影响。
对每个分治中心维护一个大小为 \(\max\text{dep}\) 的桶,设两个指针维护最小和次小的位置。
如何修改?点分树将包含 \(u\) 的路径分为 \(\log\) 种,将这些对应位置减 \(1\),并同时维护指针。
全局答案如果用可删堆维护会多一个log,同样指针维护,因为答案是不降的。
时空复杂度 \(O((n + q)\log n)\)。
P5921 [POI1999] 原始生物
一个自然的想法是连边 \(l \to r\)。
问题转化为:添加最少的边,使得原图存在一条欧拉路径。
独立考虑每个弱连通分量,显然 \(\sum in_u = \sum out_u\),则 \(\sum \vert in_u - out_u\vert \equiv 0 \pmod 2\)。
如果 \(\sum \vert in_u - out_u\vert \le 2\),存在欧拉回路/路径。
如果 \(\sum \vert in_u - out_u\vert = 4\),找到 \(in_u > out_u,\ in_v < out_v\),连边 \(u \to v\)。
接下来同理,新增边数为 \(\frac{\sum \vert in_u - out_u\vert}{2} - 1\)。
P5944 [POI2002] 出圈游戏
稍微转化一下就是 \(k \bmod n = b_1,\ k \bmod (n - 1) = b_2 \cdots\) 的形式。
excrt 板子,难点在于唐氏题面。
P3426 [POI2005] SZA-Template
记前缀 \(i\) 的 border 集合为 \(B_i\),所有能覆盖 \(i\) 的前缀集合为 \(T_i\)。
显然 \(T_i \subseteq B_i\),因为要同时覆盖 \(i\) 的前后缀。
-
设 \(ne_i\) 表示 \(i\) 的极大非平凡 border,对于任意 \(j \ne i,\ j \in T_i\),必须满足 \(j \in T_{ne_i}\)。
\(j \in B_{ne_i}\),即他能覆盖 \(ne_i\) 的前后缀。如果 \(j < i\) 想要覆盖 \(i\),必须先覆盖 \(ne_i\)。
-
对于 \(j_1, j_2 \in T_i\) 且 \(j_1 < j_2\),那么 \(j_1\) 一定能覆盖前缀 \(j_2\)。
border 的 border 还是 border,因此 \(j_1\) 是 \(j_2\) 的 border。
\(j_1\) 能覆盖 \(j_2\) 的前后缀,又因为 \(j_1\) 能覆盖 \(i\),\(j_1\) 能覆盖 \(j_2\)。
令 \(f_i = \min_{j \in T_i} j\),任意 \(T_i\) 中元素都能被 \(f_i\) 表示。
根据上述两个推论,要么 \(f_i = i\),要么 \(f_i \in T_{ne_i}\),而在这之中 \(f_i = f_{ne_i}\) 是最优的。
\(f_i\) 能取到 \(f_{ne_i}\) 当且仅当存在一个 \(f_j = f_{ne_i} \land j \ge i - ne_i\)。
证明:\(f_j > f_{ne_i}\),显然不行;\(f_j < f_{ne_i}\),根据 \(f_{ne_i}\) 的最小性和推论 2,\(f_j\) 不能覆盖 \(ne_i\)。
P5913 [POI2004] KAG
每个连通块只能通过第一类操作合并为原图,单独考虑每个连通块。
注意到,第二类操作等价于补图意义下的第一类操作。
- 依次检查原图每个极大连通块。
- 建出补图,依次检查每个连通块的补图。
交替执行上述操作,若最终能被拆分为若干单点,则原图是 \(\texttt{c-algae}\) 的。
操作一是 \(O(n + m)\) 的,操作二是 \(O(n^2)\) 的。
每次操作二至少消耗 \(O(n)\) 条边(最坏情况左图 \(1\) 个点,右图 \(n - 1\) 个点),故至多执行 \(O(\frac{m}{n})\) 轮。
优化操作二,如何找到 \(u\) 在补图中的连通块?
链表维护当前未被拓展的点,对应当前点枚举所有未被拓展的点。
如果他们没有边相连,说明他们在补图上连通,把他加入队列并从链表中删除。
每个点只会拓展一次,而"有边相连"的情况只会发生 \(m\) 次,复杂度 \(O(n + m)\)。
总复杂度 \(O((n + m) \frac{\min(m, n^2)}{n}) = O((n + m) \sqrt m)\)。
P3429 [POI2005] DWA-Two Parties
假设答案为 \(n\):
高斯消元 \(O(\frac{n^3}{w})\) 求解。
现在证明该方程组一定有解。
无解当且仅当从中选出若干方程,他们异或起来满足左边各项系数为 \(0\),右边为 \(1\)。
第 \(i\) 个点对应方程被选中当且仅当 \(i \in S\)。
-
有奇数个奇度点被选,这保证了右边为 \(1\)。
-
每个被选奇度点,有奇数个相邻点被选;其他所有点(不一定被选)有偶数个相邻点被选。
选 \(i\) 会使其所有相邻点的系数异或一,上述约束保证了左侧各项系数为零。
构造一个新图,满足点集仍是原图点集,边集为 \(\left\{(u, v)\mid u \in S \land v \in S\right\}\)。
新图中,\(S\) 中奇度点度数为奇,其他点度数为偶。
奇数个奇度点度数仍是奇数,这与无向图度数和为偶数矛盾,故 \(S\) 不存在,原方程组恒有解。
P5919 [POI2004] MAK
\(i\) 向 \(p_i\) 连边,\(k\) 轮后 \(a_i\) 的值即 \(i\) 向父亲跳 \(k\) 步到的位置。
不难得到一个置换的 \(\texttt{order}\) 就是其所有环长的 \(\text{lcm}\)。
问题转化为,求一组正整数 \(x_1 + x_2 + \cdots + x_m = n\) 使得的 \(\text{lcm}(x_1, x_2, \cdots, x_m)\) 最大。
如果已知 \(\{x\}\),如何最小化字典序?
对于一个环 \(\{e_1, e_2, \cdots, e_k\}\),默认 \(e_i \le e_{i + 1}\)。
其能产生的最小字典序为 \(p(e_i) = e_{i + 1},\ p(e_k) = e_1\)。
一个环所占值域一定是一段连续区间。
贪心的将长度小的环放在前面,从 \(1\) 到 \(n\) 依次填充每个环,因为这样能使 \(e_1\) 尽可能往前。
-
如果 \(\text{lcm}\) 相同,自环越多越好。
贪心的将自环放在最开头,显然自环多的字典序小。
-
一定存在一组最优方案,使得所有环长两两互质。
假设 \(\gcd(x_i, x_j) = d > 1\),令 \(x_i \to x_i / d\),\(\text{lcm}\) 不变,多的总和可以作为自环。
-
一定存在一组最优方案,使得所有环长都是质数幂次。
假如 \(x\) 形如 \(p^aq^bc\),其中 \(p, q\) 是不相同的质数,\(c\) 没有质因子 \(p, q\)。
显然将 \(x\) 拆成 \(p^a\) 和 \(q^bc\) 不改变总的 \(\text{lcm}\),而总和 \(p^a + q^bc < p^aq^bc\),可以多出自环。
证明就是对于大于 \(1\) 的正整数 \(a \ne b\),\((a - 1)(b - 1) > 1 \implies a+ b < ab\)。
考虑筛出 \(10^4\) 内的所有质数。
较大的质数基本用不到,实测取前 \(200\) 个可以通过本题。
\(f(i, j)\) 表示考虑了前 \(i\) 个质数,在总和不超过 \(j\) 的情况下的最大 \(\text{lcm}\),同时 \(g(i, j)\) 记录决策。
由于只要比对大小,我们不妨将 \(f(i, j)\) 取对数,这样就能在 double
下比较。
如果最优方案的总和不满 \(n\),一直补自环即可。
P6756 [BalticOI2013] Brunhilda’s Birthday
记 \(f_n\) 表示 \(n\) 的答案,显然 \(f_n = 1 + \min f_{\lfloor\frac{n}{p_i}\rfloor\cdot p_i}\)。
考虑填表法,\(f_n + 1 \to f_{[n + 1, n + p_i - 1]}\),其中 \(p_i \mid n\),只有最大的 \(p\) 有用,记作 \(h_n\)。
下面说明 \(f\) 是单调的。
假设 \(f_i \ne f_{i + 1}\),设他们的转移点分别为 \(j, k\)。
如果 \(k = i\),\(f_{i + 1} = f_i + 1\)。
否则 \(k < i\),既然 \(k\) 能覆盖到 \(i + 1\) 那么他也能到 \(i\),\(f_i\) 从 \(j\) 转移过来说明 \(j\) 比 \(k\) 优,即 \(f_i < f_{i + 1}\)。
设 \(r_{i + 1} = \max_{f_n = i} n + h_n - 1\),那么 \(f_i\) 就是找到最小的一个 \(x\) 满足 \(r_x \ge i\),容易维护。
P9179 [COCI2022-2023#5] Logaritam
对于 \(n = p_1^{a_1}p_2^{a_2} \cdots p_k^{a_k}\),\(x_n = a_1x_{p_1} + a_2x_{p_2} + \cdots, a_kx_{p_k}\)。
一个数改动,说明其至少有一个质因子发生改动。
一个质数改动,只会改动其所有倍数,且不产生矛盾,贪心的选最大指数即可。
P9180 [COCI2022-2023#5] Slastičarnica
在钦定当前左端点位置,满足了几个要求下,显然右端点越远越好。
设 \(f(i, p)\) 表示满足了 \(i\) 个要求,左端点在 \(p\) 时,最大的右端点。
设 \(a(i, p)\) 大于等于 \(p\) 的第一个位置 \(j\) 满足 \([j, j + d_i)\) 全部 \(\ge s_i\)。
同理 \(b(i, p)\) 表示小于等于 \(p\) 的第一个位置满足 \((j - d_i, j]\) 全部 \(\ge s_i\)。
以上信息容易 \(O(nq)\) 预处理,其中 \(q \gets \min(q, n)\)。
考虑第 \(i\) 个要求是用前缀还是后缀满足的(转移方程省略第一维):
P2048 [NOI2010] 超级钢琴
通过某种方式找到前 \(k\) 大的区间。
设 \(f(i, l, r)\) 表示以 \(i\) 为左端点,使 \(s_p - s_{i - 1}\) 最大的右端点 \(p\),\(p \in [l, r]\)。
容易st表预处理后 \(O(1)\) 得到。
假设当前全局最大值为 \(p = f(i, l, r)\),去掉 \([i, p]\) 后,答案还可能从 \(f(i, l, p - 1)\) 和 \(f(i, p + 1, r)\) 产生。
优先队列维护一个bfs状物即可。
NFLSOJ 12394
题意:给定 \(a, b\),称 \(a\) 的一个子序列 \(\{p_1, p_2, \cdots, p_k\}\) 是好的,当且仅当 \(\forall i,\ a_{p_{i + 1}} > b_i \times a_{p_i}\)。
求最长好子序列的长度,$1 \le n \le 10^6, 1 \le a_i, b_i $。
\(f(i, j)\) 表示考虑了 \(1 \sim i\),长度为 \(j\) 的好子序列末尾元素最小值。
\(f^{\prime}_j \gets a_i\) 当且仅当 \(a_i > f_{j - 1} \times b_{j - 1}\)。
注意到,\(i\) 相同时,\(f(i, j)\) 单调递增(好序列中元素是严格递增的)。
找到第一个 \(k\),满足 \(f(i - 1, k) > a_i\)。
对于 \(j < k\),\(a_i\) 显然不能更新;对于 \(j > k\),\(f(i - 1, j - 1) > a_i\),因此 \(a_i\) 没有机会大于 \(f(i - 1, j - 1) \times b_{j - 1}\)。
综上所述,每次最多改动一个位置,且这个位置唯一确定,时间复杂度 \(O(n\log n)\)。
P3226 [HNOI2012] 集合选数
构造一个矩阵:
1 2 4 8 16 32 ...
3 6 12 24 48 96 ...
9 18 36 72 ...
27 ...
设左上角元素为 \(e\),那么 \((i, j)\) 中元素为 \(e3^i2^j\),不会有重复。
问题转化为,在这个矩阵中,选出一个集合,满足没有相邻的两个元素被同时选中的方案数。
行列都只有 \(\log_2n,\log_3n\) 级别,可以状压dp。
然而光是这一个矩阵不能覆盖所有 \(1 \sim n\),对于所有的 \(2 \nmid e \land 3 \nmid e\),都能建出这么一个矩阵,且不同矩阵中不存在相同元素。
根据乘法原理,每个矩阵的结果相乘即可。
NFLSOJ 971
题意:构造一颗恰有 \(k\) 条直径的树,\(1 \le k \le 5\times 10^6\)。
限制:\(2 \le n \le 5000,\ 0 \le w \le 10^5\),\(w\) 表示边权。
![](https://cdn.luogu.com.cn/upload/image_hosting/r0d0zdzr.png)
这样就花费 \(x + y + z + 4\) 个点构造出一棵拥有 \(xy + xz + yz\) 条直径的树。
类似的,可以构造出一棵 \(x + y + 3\) 个点 \(xy\) 条直径的树。
打表验证,上面两种已经覆盖了全部情况。
P6869 [COCI2019-2020#5] Putovanje
统计每条边遍历次数,树上差分解决。
P6742 [BalticOI 2014 Day2] Portals
自己手玩一下,存在一种最优方案使得两个传送门是从同一点发射的。
肯定是挑离自己最近的一个墙壁发射一个,然后传送到另一个方向的墙壁。
预处理每个点到四个方向墙壁中的最短距离,然后跑最短路即可。
HDU 6883
题意:给定 \(n\) 个堆,每个堆恰好 \(3\) 个物品,从上至下价值分别为 \(a_i, b_i, a_i\)。
选出一个物品必须先选其上方所有物品,\(f(i)\) 表示选出恰好 \(i\) 件物品的最大价值和。
给定 \(k\),求 \(\bigoplus_{i \le k}f(i)\),\(n \le 5 \times 10^6,k \le 3n\)。
每个堆对答案的贡献只有四种:不选,\(a_i\),\(a_i + b_i\),\(a_i + b_i + a_i\)。
把一个堆拆为两个互相独立的物品:体积 \(1\) 价值 \(a_i\),体积 \(2\) 价值 \(a_i + b_i\)。
决策新物品选或不选就能覆盖原问题的全部情况。
贪心的按 \(\dfrac{\text{价值}}{\text{体积}}\) 将新物品从大到小排序。
如果某个前缀的体积和恰好为 \(i\),那么 \(f(i)\) 即为这个前缀的价值和。
否则这个前缀恰好比 \(i\) 大一,说明最后选的物品体积为 \(2\)。
两种调整办法:在已选物品中找到体积为 \(1\) 最小价值并将其删除;不选当前物品,在未选物品找到体积为 \(1\) 的最大价值。
排序部分如果桶排可以做到 \(O(n)\),否则需要轻微卡常。
P7913 [CSP-S 2021] 廊桥分配
一眼三分,然后假了,因为存在一段连续的函数值相同。
假设一开始有无限多个廊桥:
按照时间顺序给每个飞机分配当前可用编号最小的廊桥,设 \(i\) 对应 \(c_i\)。
如果限制廊桥个数只有 \(k\) 个,\(i\) 能分配到当且仅当 \(c_i \le k\)。
处理一个前缀和数组然后枚举 \(k\) 即可。
P7915 [CSP-S 2021] 回文
根据第一步的决策进行分类讨论,假设第一步选 L
。
找到和 \(a_1\) 相同的位置 \(k\),把整个序列分为两部分:\([2, k - 1],\ [k + 1, n]\)。
问题转换为:给你两个栈 \(p, q\),每次弹出某个栈的栈顶,要求最后序列回文,且操作的字典序最小。
还是考虑第一步,如果要弹出 \(p\) 的栈顶,那么这个元素必须同时出现在某个栈的栈底,这样才能回文。
在 \(p, q\) 都能弹出时优先弹 \(p\),最小化字典序。
把栈顶和对应栈底都弹出后,变为了一个规模为 \(n - 2\) 的子问题(原来是 \(n - 1\)),继续做即可。
P7914 [CSP-S 2021] 括号序列
基本独立想出来的(因为用了std调试)。
()
、(S)
是好的,S
表示仅由不超过 \(k\) 个字符*
组成的非空字符串。- 如果
A
和B
是好的,那么AB
、ASB
是好的。 - 如果
A
是好的,那么(A)
、(SA)
、(AS)
是好的。
设 \(f_{l, r}\) 表示 \([l, r]\) 是好的的方案数,\(g_{l, r} = 0/1\) 表示 \([l, r]\) 是否有可能成为一个 S
串。
设 \(c_{l, r}\) 表示 \([l, r]\) 形如 A
或 S
或 SA
或 AS
的方案数。
考虑如何计算 \(f\),如果 \([l, r]\) 是第三种方式生成的:\(f_{l, r} \gets c_{l + 1, r - 1}\)。
如果 \([l, r]\) 是第二种方式生成的,枚举与 \(l\) 匹配的右括号位置:
对于某个固定的 \(i\),\(g_{i, j}\) 是单调的,预处理每个 \(i\) 对应最大的 \(j\) 满足 \(g_{i, j} = 1\),记作 \(p_i\)。
那么:
后面那个用后缀和优化下就能变成 \(O(n^3)\)。
P7960 [NOIP2021] 报数
小常数 1e7 单 log 是能冲过 1s 的。
P7961 [NOIP2021] 数列
设 \(f(i, j, k, p)\) 表示考虑了 \(0 \sim i - 1\),填了 \(j\) 个数,当前 \(S\) 中有多少位 \(1\),进 \(p\) 位到 \(i\) 的方案的贡献。
往后转移,决策放了 \(l\) 个数等于 \(i\):
复杂度 \(O(n^4m)\)。
P7962 [NOIP2021] 方差
假设现在有四个数 \(a, b, c, d\),对第二个数做题中变换:\(a, a + c - b, c, d\)。
变换前后差分数组分别为 \(b - a, c - b, d - c\) 和 \(c - b, b - a, d - c\)。
不难发现,该操作等价于交换差分。
感性理解一下,存在一组最优解使得差分数组是单谷的,因为这样能使数组尽可能平均。
将差分数组排序,从小到大插入,每次插在前面或后面。
化简答案:
直接维护两个东西的差不是很好做,考虑把一维记在状态里。
\(f(i, j)\) 表示考虑了前 \(i\) 个差分,\(\sum a_i\) 为 \(j\) 时最小的 \(\sum a_i^2\)。
转移考虑每个 \(d_i\) 插在前面还是后面(最后再插入 \(a_1\))。
差分为 \(0\) 插在开头最优,不发生转移;非 \(0\) 的差分只有 \(\min(a, n)\) 个,稍加剪枝可以通过。
时间复杂度 \(O(na^2)\)。submission
CF2035B
题意:构造一个长度为 \(n\),只包含 \(3, 6\) 且能被 \(66\) 整除的数,最小化字典序。
\(n\) 的构造可以在 \(n - 2\) 的构造之前加 \(33\),因为 \(66 \mid 3300\)。
不会出现 \(n - 1\) 的构造之前加 \(3\) 的情况,因为 \(6 \times 11 \nmid 3\times 2^i\times 5^i\)。
\(n = 2\) 的构造为 \(66\);\(n = 1\) 或 \(3\) 无解,\(n = 5\) 构造为 \(36366\)。
P3561 [POI2017] Turysta
【参考】:竞赛图性质研究。
结论1:竞赛图强连通缩点后的DAG呈链状,且前面的所有点向后面的所有点连边。
归纳证明,逐个加入强连通分量。
设橙色点为当前加入的 scc:如果 \(x\) 连向所有点,放在链头;
否则 \(x\) 的入边都在出边前面(否则成环),找到对应位置插入即可。
结论2:任意竞赛图存在一条哈密顿链。
增量构造,考虑在当前链的基础上加入点 \(x\)。
如果 \(x\) 指向链头或链尾指向 \(x\),直接接在两端即可。
否则,用 \(1\) 表示指向 \(x\),\(0\) 表示被 \(x\) 指向,那么原链可以表示为 \(1 \cdots\cdots 0\)。
一定存在相邻的 \(10\),将 \(x\) 插入对应两点当中。
时间复杂度 \(O(n^2)\)。
结论3:强连通的竞赛图一定存在哈密顿圈。
假设已经找出了一条链。
找到指向链头的一个点 \(t\),组成初始环 \(s \to nxt_s \to \cdots \to t \to s\)。
一定存在这么一个 \(t\),否则 \(s\) 只有出边没有入边,\(nxt_s\) 不能到达 \(s\),与强连通矛盾。
考虑加入 \(i = nxt_t\)。
如果 \(i\) 指向 \(s\),直接拓展:断开 \(t \to s\),接上 \(t \to i \to s\)。
否则找到第一个 \(x\) 使得 \(i \to x\),构造如下路径:
![](https://cdn.luogu.com.cn/upload/image_hosting/h4o31592.png)
即设 \(pre_x = y\),构造 \(i \to x \to \cdots t \to s \to \cdots y \to i\)。
因为 \(x\) 是第一个 \(i \to x\),因此 \(y, i\) 之间的关系一定是 \(y \to i\)。
如果找不到 \(x\) 呢?
不妨先跳过当前点继续往下走,直到找到一个 \(i\) 存在 \(i \to x\)(一定能找到,否则不强连通)。
![](https://cdn.luogu.com.cn/upload/image_hosting/u27x2odz.png)
即:\(x \to \cdots t \to s \to \cdots y \to nxt_t \to \cdots i \to x\)。
同时更新 \(s\) 为 \(x\),\(t\) 为 \(i\)。
本题做法:
缩点,对于每个强连通分量跑出哈密顿回路。
对于每组询问,从 \(i\) 点所在连通分量开始,沿着DAG链往下把所有回路拼接起来。
CF1685C
用 \(\pm 1\) 替代原串,设 \(a\) 为前缀和数组,合法当且仅当 \(\forall i,\ a_i \ge 0\)。
一个重要的观察:答案不超过 \(2\)。
设 \(p\) 为 \(a_i\) 最大的位置,翻转 \([1, p]\),翻转 \([p + 1, 2n]\) 得到的序列一定合法。
对于 \(i \le p\),\(a_p - a_{p - i} \ge 0\),对于 \(i > p\),\(a_p + a_{2n} - a_{2n - p} \ge 0\),符合条件。
答案为零容易判断,现在只要考虑答案是否为 \(1\)。
假设翻转 \([l, r]\) 后合法,需要满足:\(\forall i < l\land i \ge r,\ a_i \ge 0\),\(\forall l \le i \le r,\ a_{l - 1} + a_r - a_{i - 1} \ge 0\)。
设 \(s, t\) 分别为第一和最后一个 \(a_i < 0\) 的位置。
那么 \(l < s \land r > t\),\(\max [l - 1, s)\cup [s, t] \cup (t, r - 1] \le a_{l - 1} + a_r\),
贪心的选 \(a_{l - 1}\) 和 \(a_r\) 最大的,这样只要考虑 \([s, t]\) 的限制。
**マス目と整数 **(link)
前面忘了,黑降绿,后面忘了。
a b
c d
e f
\(a + d = c + b,\ c + f = d + e \implies a - b = c - d = e - f\)。
推广到相邻两列差值相同,等价于任意两列差值相同(相同行元素)。这是条件成立的充要条件。
如果同时存在 \(a_{x, i},\ a_{x, j}\) 已经确定,\(i\) 向 \(j\) 连边,边权 \(a_{x, i} - a_{x, j}\)。
带权并查集判断是否出现矛盾。
否则所有列的差值关系都被确定,接下来考虑点权非负的限制。
对于每个连通块,选出基准列 \(i\),算出其在该连通块限制下可能的最小权值 \(\min a_{x,j} - d_{j - i}\)。
以该基准列出发,跑出该连通块其他权值,看是否非负即可。
CF883D
二分答案 \(d\),然后就是CF1476F的弱化。
设 \(f_i\) 表示前 \(i\) 个吃豆人能覆盖的最远右端点,设第 \(i\) 个吃豆人的位置为 \(p_i\)。
如果 \(i\) 往右,当且仅当 \(f_{i - 1}\) 到 \(p_i\) 之间没有豆子了,\(f_i \gets \max(f_{i - 1}, p_i + d)\)。
如果 \(i\) 往左,当且仅当 \(f_{i - 1}\) 到 \(p_i - d\) 之间没有豆子,\(f_i \gets p_i\)。
\(i\) 往左可能使某些 \(j\) 往左的贡献无效(不用 \(j\) 也能覆盖),可以让这些 \(j\) 指向右边从而覆盖更远。
如果某个 \(j < i\) 能往右,\(i - 1\) 也能往右,且 \(p_{i - 1} + d\) 最大。
因此如果 \(i\) 往左,且 \(f_{i - 2}\) 到 \(p_i - d\) 之间没有豆子,\(f_i \gets p_{i - 1} + d\)。
时间复杂度 \(O(n\log n)\)。
P11290 【MX-S6-T2】「KDOI-11」飞船
\(x = 1\) 没用。
设当前速度为 \(v\),如果加速后更优:\(\frac{d}{vx} + t < \frac{d}{v}\)。
当 \(v > d\) 时,由于 \(t \ge 1\),必然有 \(\frac{d}{vx} + t \ge \frac{d}{v}\),因此最优方案下速度不大于最长距离。
\(f_{i, j, k}\) 表示考虑了前 \(i\) 个加油站,速度为 \(2^j3^k\) 的最小时间。
二分出终点前第一个加油站位置并统计答案即可。
CF461E
如果 \(s\) 确定,如何求出其最小操作数?
\(g_i\) 表示前缀 \(i\) 最少被分成多少段,\(g_i\) 能从 \(g_j + 1\) 转移当且仅当 \((j, i]\) 是 \(t\) 的子串。
注意到 \(g_{i} \ge g_{i - 1}\),因为任意 \(i\) 的方案都能砍掉 \(s_i\) 后变成 \(i - 1\) 的方案。
因此 \(i\) 的转移点为最小的 \(j\) 满足 \((j, i]\) 是 \(t\) 的子串。
有如下贪心:对于每一段,能延伸就延伸(在 \(t\) 的 sam 上跑,有转移边就走,否则回到根)。
在段数相同的情况下要最小化总长度,这样才能在总长度确定时最大化段数。
设 \(f(k, i, j)\) 表示已经拼了 \(k\) 段,以字符 \(i\) 开头且不能再往后延伸一个字符 \(j\) 的最小总长度。
倍增优化:\(f(2^k, i, j) \gets f(2^{k - 1}, i, x) + f(2^{k - 1}, x, j)\)。
问题转化为求 \(f(1, i, j)\)。
其代表的子串在将来一定是接一个 \(j\) 开头的段,并产生 \(2\) 的贡献。
把以 \(i\) 开头的字符串 \(s\) 分成三类:
- 是 \(t\) 的子串且后面不能加 \(j\),在后面接一个 \(j\) 开头的段,恰好产生两个段。
- 是 \(t\) 的子串且后面能加 \(j\),不一定能产生两个段。
- 不是 \(t\) 的子串,已经产生至少两个段了,哪怕新接的段不产生贡献,贡献仍然至少为二。
因此在相同长度下,一三比二更优。
固定长度为 \(k\),第二类有 \(x = O(n)\) 种,一三加起来有 \(4^{k - 1} - x\)。
存在一三串当且仅当 \(4^{k - 1} - x > 0\),取 \(k = 11\) 足矣。
对所有后缀建出树高为 \(11\) 的字典树即可求出所有有用的 \(f(1, i, j)\)(可能存在大于 \(11\),但是没用)。
统计答案:从高到低枚举 \(2^k\),\(h_{i, j}\) 表示 \(i\) 开头,后面接不了 \(j\),在当前答案下的最小长度。
由于有“不能接”这一限制,贪心的让 \(h_{i, j} < n\),并在最后补一个 \(j\)(体现在答案上就是加 \(1\))。
P9195 [JOI Open 2016] JOIRIS
如果所有 \(a_i\) 模 \(k\) 同余,那么容易一直放竖条把整个消掉。
在模 \(k\) 意义下考虑整个问题。
存在一种构造,是一个长度为 \(k\) 的连续段不变,其他位置减 \(1\):
设 \([i, i + k)\) 的最大值为 \(x\),在所有其他列上不断放竖条直到超过 \(x\)。
在 \(i\) 放横条,这样就能把这一行消掉,达到上述目的。
从左往右做一遍,这样可以使 \([1, n - k + 1]\) 模 \(k\) 同余,然后从右往左再做一遍
P9350 [JOI 2023 Final] Advertisement 2
把 \(\vert X_i - X_j\vert \le E_i - E_j\) 按照 \(X\) 的大小关系拆开。
这两种情况又能统一为 \(X_i - X_j \le E_i - E_j\) 且 \(X_j - X_i \le E_i - E_j\)。
这是一个二维偏序问题,\(E_i - X_i\) 看作横坐标,\(E_i + X_i\) 看作纵坐标。
\(j\) 能被 \(i\) 影响当且仅当 \(j\) 的矩形被 \(i\) 覆盖。
按照横纵标排序,跑一个纵坐标的单调栈即可。
P3557 [POI2013] GRA-Tower Defense Game
称距离为 \(1\) 的覆盖为覆盖,距离为 \(2\) 的为拓展。
证明以下策略是正确的:随便找到一个未被染色的点并往外拓展。
设原图一个大小为 \(k\) 的点覆盖为 \(S\) 。
从 \(x\) 拓展能够花费 \(1\) 的距离到和 \(x\) 有边的 \(y \in S\),剩下 \(1\) 的距离相当于 \(y\) 在覆盖。
每次至少会走到一个新的 \(y\)(从 \(y\) 开始没覆盖过),否则:
- 和 \(x\) 距离为 \(1\) 的点集中不存在 \(y \in S\),那么 \(S\) 不是原图的点覆盖。
- 存在 \(y\in S\) 已经被用过,这和 \(x\) 未染色矛盾。
因此 \(x\) 的数量不超过 \(k\)。
CF1592D
由于 \(\gcd(a, b, c) \le \gcd(a, b)\),题目所求就是最大边权。
如何让询问的点集连通?
可以在长度为 \(2n - 1\) 的欧拉序上二分,满足 \(a_i\) 和 \(a_{i - 1}, a_{i + 1}\) 之间都有边。
询问次数为 \(1 +\log_22000 = 12\)。
NFLSOJ 10305
题意:给定无向图 \(G = (V, E)\),是否存在一个序列 \(v_0\sim v_{k - 1}\) 满足:
- 不存在 \(v_i = v_j\)。
- \((v_i,v_{(i + 1)\bmod k}) \in E\)。
- \(\sum c_{v_i} > \lfloor\frac{k}{2}\rfloor\)。
其中 \(c_i\) 是 \(i\) 的点权,最多三位小数。
数据范围:\(n \le 500, m \le 2000, 0 \le c_i \le 1\)。
小数完全没用,因为不等号两边可以同时乘 \(1000\) 变成整数。
设边权 \(w(u, v) = c_u + c_v - 1\),那么题目所求等价于:
- 一条正权边。
- 一个边权和为正的环。
- 一个边权和大于 \(-1\) 的奇环(下取整的缘故)。
显然如果第二种情况存在,必然第一种情况存在,因此只需判断有无正权边。
现在所有边为负,要找一个边权和最大的奇环。
拆点,设 \(u\) 奇点为 \(u_1\),偶点为 \(u_0\),\(u_i\) 向 \(v_{i \oplus 1}\) 连边。
对每个 \(u_i\) 跑最长路(dij),判断 \(dis_{u_{\oplus 1}}\) 是否大于 \(-1\),时间复杂度 \(O(nm\log m)\)。
当且仅当 d[x] + w > d[y]
才松弛可以使最长路上的点不重复。
但是没有保证原图上的点也不重复,即可能出现同一个点的奇点偶点同时出现在路径中的情况。
取这两个点之间的一段作为新环,边数为奇,且总和一定大于 \(-1\)。
AT_code_festival_2017_qualc_f
设 \(S_A = \{i_1, i_2,\cdots,i_{n/3}\}\) 为 \(A\) 最终吃掉的寿司在 \(\{a\}\) 中的下标,同理 \(S_B,S_C\)。
假设已经知道 \(S_A,S_B,S_c\),怎么求符合条件的排列 \(\{c\}\) 个数?
从后往前考虑。\(a_{i_{n/3}},b_{j_{n/3}}\) 在 \(c\) 中的位置一定大于 \(k_{n/3}\),否则 \(C\) 会选 \(a_{i_{n/3}}\) 或 \(b_{j_{n/3}}\)。
即这三个数在 \(c\) 中的相对位置一定形如 \(c_{k_{n/3}}a_{i_{n/3}}b_{j_{n/3}}\) 或 \(c_{k_{n/3}}b_{j_{n/3}}a_{i_{n/3}}\)。
再考虑倒数第二步,同样只要满足 \(a, b\) 对应元素在 \(c\) 后面就行。
不会对第 \(n/3\) 步产生影响,因为在第 \(n/3\) 步时这些元素都被删掉了。
此时 \(c\) 中已经插入了三个位置,\(c_{k_{n/3 - 1}}\) 肯定是插在 \(c_{k_{n /3}}\) 前面,而 \(a_{i_{n/3 - 1}}, b_{j_{n/3} - 1}\) 分别有 \(4\) 和 \(5\) 个空格可插。
因此操作序列确定时,\(\{c\}\) 的个数为 \(\prod_{i = 1}^{n/3} (3i - 1)(3i - 2)\)。
问题转化为有多少合法的 \(\{S_A, S_B, S_C\}\)。
当 \(S_A,S_B\) 确定时,有多少合法的 \(S_C\)?
合法当且仅当对于任意 \(1\le t \le\frac{n}{3}\) 都满足:
- \(c_{k_t} \notin a[1 \sim i_t] \cup b[1 \sim j_t]\) 。
- \(b_{j_t} \notin a[1 \sim i_t] \cup c[1 \sim k_t]\) 。
- \(a_{i_t} \notin b[1 \sim j_t] \cup c[1 \sim k_t]\) 。
计算系数时,已经保证了 \(a_{i_t}, b_{j_t} \notin c[1 \sim k_t]\)。
现在只要保证 \(\forall t, a[1 \sim i_t] \cup b[1 \sim j_t]\) 中 \(a_{i_{t}}\) 只出现一次,\(b_{j_t}\) 只出现一次,\(c_{k_t}\) 不出现。
考虑 \(c_{k_t}\) 有哪些值不能取?
- \(t^{\prime} > t\) 的所有 \(a_{i_{t^{\prime}}},b_{j_{t^\prime}},c_{k_{t^\prime}}\),共 $3(\frac{n}{3} - t) $ 个。
- \(a[1 \sim i_t] \cup b[1 \sim j_t]\) 中的所有元素。
上下两部分无交,元素总数为 \(n\),因此 \(c_{k_t}\) 可以取的个数为 \(3t - \vert a[1 \sim i_t] \cup b[1 \sim j_t]\vert\)。
为什么要从后往前考虑?因为如果从前往后,不能取的上下两部分有交,不容易计算。
因此合法 \(S_C\) 的个数为 \(\prod 3t - \vert a[1 \sim i_t] \cup b[1 \sim j_t]\vert\)。
设计一个DP:\(f_{t, i, j}\) 表示填了 \(t\) 个位置,\(i_t = i, j_t = j\) 的方案数:
前缀和优化一下就能 \(O(1)\) 转移。
[ARC172D] Distance Ranking
记 \(a_{i, j}\) 表示点 \(i\) 的第 \(j\) 维坐标,\(L = 10^8\)。
构造 \(a_{i, i} = L, a_{i, j < i} = 0, a_{i, j > i} = rk_{i, j}\)。
现在考虑 \(i, j(j > i)\) 距离的平方:\(L^2 + (rk_{i, j} - L)^2 + \sum rk_{i, k}^2 + \sum (rk_{i, k} - rk_{j, k})^2\)。
注意第二项展开后有 \(-2rk_{i, j}L\),如果 \(rk\) 差一,带来的影响远比后面大。
P5361 [SDOI2019] 热闹的聚会与尴尬的聚会
题意:找一个导出子图,设其最小度数为 \(p\);找一个独立集,设其大小为 \(q\)。
需要满足:\(\left\lfloor \frac{n}{p+1} \right\rfloor\! \le q\) 且 \(\left\lfloor \frac{n}{q+1} \right\rfloor\! \le p\)。
分析一下这个奇怪的条件:
- \(p + 1\mid n \implies \frac{n}{p+1} \! \le q\)。
- \(p + 1\nmid n \implies \frac{n}{p+1} < q + 1\)。
即不管整不整除,两个限制都等价于 \((p + 1)(q + 1) > n\)。
\(p, q\) 肯定都是越大越好。
最大化 \(p\) 是容易的:每次删除度数最小的点(不可能不删他而使答案变大)。
最大化 \(q\)?最大独立集是 npc,没法做。
考虑如下策略:每次选度数最小的点,并删除他和他的邻域。
被选点度数一定不超过 \(p\),否则剩余点就是第一问的更优解,矛盾。
因此每选一个点,最多新删除 \(p + 1\) 个点。
一直选点直到所有点被删除,有 \(q\times (p + 1) \ge n \implies (p + 1) (q + 1) > n\) 。
P6982 [NEERC2015] Jump
题意:每次询问一个 01 串 \(t\),设 \(k = \vert s\cap t\vert\),当且仅当 \(k = \frac{n}{2}\) 或 \(n\) 时返回 \(k\),否则返回 \(0\)。
在不超过 \(n + 500\) 次询问后猜出 \(s\)。\(1 \le n \le 1000\)。
考虑 \(t_0 = 000, t_1 = 100, t_2 = 110,\cdots, t_{n - 1} = 111\)。
在这 \(n\) 个询问当中,一定存在一次 \(k = \frac{n}{2}\)。
证明:\(\vert t_0 \cap s\vert\) 和 \(\vert t_{n - 1} \cap s\vert\) 一定分布在 \(\frac{n}{2}\) 两侧,而 \(t_i \to t_{i + 1}\) 至多使交集大小变化 \(1\),因此能遍历所有取值。
现在已经得到了一个交集为 \(\frac{n}{2}\) 的串 \(t\)。
设 \(c_i = [t_i = s_i]\)。
对 \(t\) 中 \(i, j\) 两个位置取反后再询问,如果返回 \(\frac{n}{2}\),说明 \(c_i \ne c_j\),否则 \(c_{i} = c_j\)。
固定 \(t_0\),花费 \(n - 1\) 次询问可以得到 \(c_i\) 和 \(c_0\) 的关系。
枚举 \(c_0\) 是 \(0\) 还是 \(1\),剩下部分唯一确定。
这样我们就得到了一个最坏询问次数为 \(2n + 1\) 的确定性算法。
考虑随机来得到第一步:一次正确的概率为 \(\frac{\binom{n}{n/2}}{2^n} \approx O(\frac{1}{\sqrt {2n}})\),随机 \(499\) 轮的正确性是有保证的。
QOJ 7864. Random Tree Parking
题意:给定一棵树,求长度为 \(n\) 的序列 \(\{a\}\),满足:
枚举 \(i = 1\) 到 \(n\),将 \(a_i\) 祖先中深度最大的未染色点染色(包含本身),使得 \(n\) 次操作后所有点被染色。
数据范围:\(2 \le n \le 10^5\),且 \(i\) 的父亲随机在 \([1, i - 1]\) 中生成。
注意到如下事实:一个合法的 \(\{a\}\) 的任意排列都是合法的。
考虑进行子树 DP,统计 \(u\) 子树内的序列 \(\{b\}\),满足 \(b = \left\{a_i \mid a_i \in \text{subtree}(u)\right\}\)。
把所有属于 \(u\) 子树中的 \(a_i\) 都操作后会发生什么?整个 \(u\) 子树都被染色,且有可能往上染到 \(u\) 到某个祖先。
设 \(f_{u,i}\) 表示 \(u\) 子树内的序列 \(b\) 个数,使得操作后染到 \(u\) 的 \(i\) 级祖先。
我们可以知道 \(b\) 的大小为 \(sz_u + i\)。
现在考虑合并 \(u\) 和儿子 \(v\)(此时先不把 \(u\) 放到 \(\{b\}\) 里,只考虑子节点):
\(sz_u\) 表示已经合并的子树总大小。
现在往子节点组成的序列中插入 \(u\),枚举 \(u\) 的个数 \(i\):
最后 \(sz_u \gets sz_u + 1\)。
由于整棵树随机,树高期望 \(O(\log n)\),因此时间复杂度 \(O(n \log^2 n)\)。
QOJ 8049. Equal Sums
朴素 DP:\(f(i, j, k)\) 表示 \(\sum^i x - \sum^j y = k\) 的方案数。
前缀和优化可以做到 \(O(1)\) 转移,但是状态数是 \(O(n^2 nV)\) 的,无法通过。
考虑状态 \((i,j, k)\):
- \(k \le 0\),强制转移到 \((i + 1, j, k + x_{i + 1})\)。
- \(k > 0\),强制转移到 \((i, j + 1, k - y_{j + 1})\)。
这样就把第三维控制在了 \([-V, V]\),状态数减小为 \(O(n^2V)\)。
QOJ 9479. And DNA
题意:计数序列 \(A\),满足 \(A_i \in [0, M],\ A_i + (A_{i - 1} \text{ and } A_{i + 1}) = M\),其中认为 \(A_0 = A_N, A_{N + 1} = A_1\)。
数据范围:\(N, M \le 10^9\)。
逐位考虑,\(X_i\) 表示 \(X\) 的第 \(i\) 位。
在最低位时,满足对于所有 \(i\),\(A_{i, 0} + (A_{i - 1, 0} \text{ and } A_{i + 1, 0})\) 相同,等于 \(M_0\)。
- \(M_0 = 0\):\(A\) 的最低位要么全 \(0\) 要么全 \(1\)。
- \(M_0 = 1\):不能有连续三个 \(1\),不能有连续两个 \(0\),记方案数为 \(w_N\)。
我们发现,只有全 \(1\) 的情况才会对下一位进 \(1\),且所有 \(A_i\) 都会进位。
由于进位是统一的,这说明在更高位 \(A_{i, k} + (A_{i - 1, k} \text{ and } A_{i + 1, k})\) 全部相同依旧存在。
设 \(c_k = A_{i, k} + (A_{i - 1, k} \text{ and } A_{i + 1, k})\),需要满足 \(c_k\) 加进位等于 \(M_k\)。
设 \(f_{i, 0/1}\) 表示填了 \(0 \sim i\) 位,有没有向第 \(i + 1\) 位进 \(1\)(这里的进位对象为表达式 \(A_i + (A_{i - 1} \text{ and } A_{i + 1})\))。
-
\(M_k = 0\):
\[\begin{aligned} f_{k, 0} &= f_{k - 1, 0} & \text{这一位全填 }0\\ f_{k, 1} &= f_{k - 1, 0} + f_{k - 1, 1} \times w_N & \text{全填 }1\text{ 或 } c_k = 1 \end{aligned} \] -
\(M_k = 1\):
\[\begin{aligned} f_{k, 0} &= f_{k - 1, 1} + f_{k - 1, 0} \times w_N & \text{上一位有进位且这一位全填 }0 \text{ 或 } c_k= 1\\ f_{k, 1} &= f_{k - 1, 1} & \text{上一位有进位且这一位全填 }1 \end{aligned} \]
唯一问题只剩 \(w_N\) 怎么求。
考虑对序列 \(1011010\cdots\) 找到第一个 \(0\) 的位置:
如果这个 \(0\) 和紧跟着的 \(1\) 组成 \(01\),方案为 \(w_{N - 2}\)(删掉 \(01\) 后能对应唯一一种合法方案)。
如果组成 \(011\),方案为 \(w_{N - 3}\)。两种方案无交且覆盖所有情况。
有递推式 \(w_N = w_{N - 2} + w_{N - 3}\),边界 \(w_1 = 0, w_2 = 2, w_3 = 3\),矩阵快速幂 \(O(\log M)\) 求出。
DP 过程中有没有可能出现 \(A_i > M\) 的状态呢?不可能,否则 \(A_i + (A_{i - 1} \text{ and } A_{i + 1}) > M\)。
AT_joi2020ho_c
断环成链,\(f_{i, j, k, 0/1}\) 表示考虑了区间 \([i, j]\),收集了 \(k\) 个物品,停在左/右端点的最小时间。
P9743 「KDOI-06-J」旅行
\(f_{i, j, k, x, y}\) 表示当前在 \((i, j)\),已经花费 \(k\) 元,有 \(x\) 张往下的票,\(y\) 张往右的票剩余的方案数。
- 从上面走下来:\(f_{i, j, k, x, y} \gets f_{i -1, j, k, x + 1, y}\)。
- 从左边走过来:\(f_{i, j, k, x, y} \gets f_{i, j - 1, k, x, y + 1}\)。
- 原地买一张往下的票:\(f_{i, j, k, x, y} \gets f_{i, j, k - a_{i, j}, x - 1, y}\)。
- 原地买一张往右的票:\(f_{i, j, k, x, y} \gets f_{i, j, k - b_{i, j}, x, y - 1}\)。
如果一个方案满足两类票在 \((i, j)\) 都至少选了一个,那么他会同时被 3,4 算到。
因此最后还要减去 \(f_{i, j, k - a_{i, j} - b_{i, j}, x - 1, y - 1}\),即扣去这两个钦定在 \((i, j)\) 买的票,剩下的方案。
时间复杂度 \(O(n^5)\),空间可以滚动掉一维。
P9034 「KDOI-04」Again Counting Set
题意:对可重集 \(S\) 计数,满足:
- \(\vert S\vert = k\)。
- \(\forall x \in S,\ 0 \le x \le n\)。
- \(\prod _{x \in S} x = \min S\)。
- \(\sum_{x \in S} x = \min S + \max S + \text{mex}(S)\)。
对于第三条限制:要么 \(S\) 全 \(1\),要么 \(0 \in S\)。
如果全 \(1\),那么 \(\text{mex} = 0\),\(\sum = \min + \max\),当且仅当 \(k = 2\)。
现在设 \(T\) 表示除最大值外的所有正整数集合,有 \(\sum_T = \text{mex}\)。
感性理解一下 \(\text{mex}\) 不会很大,因为 \(\text{mex}\) 增大,\(\sum_T\) 以平方级别增长。
- \(\text{mex} = 1\),不存在 \(T\)。
- \(\text{mex} = 2\),\(T = \{1, 1\}\),最大值为 \(1\) 或 \([3, n]\) 的任何数。
- \(\text{mex} = 3\),\(T = \{1, 2\}\),最大值为 \(2\) 或 \([4, n]\) 任取,或 \(T = \{1, 1, 1\}\),最大值为 \(2\)。
- \(\text{mex} = 4\),\(T = \{1, 1, 2,\}\),最大值为 \(3\)。
- 满足 \(\text{mex} \ge 5\) 且总和最小的 \(T\) 为 \(\{1, 2, \cdots,\ \text{mex} - 2\}\),此时 \(\sum_T > \text{mex}\),因此一定无解。
P11323 【MX-S7-T1】「SMOI-R2」Happy Card
优先花三带一最优。把炸弹看成三带自己。
每种牌尽可能多的分成 \(3\) 个一组,最优可能余 \(2\) 或 \(1\)。
一张 \(1\) 能花费 \(1\) 的代价消耗一张 \(3\)。
一张 \(2\) 能花费 \(2\) 的代价消耗一张 \(3\) 或花费 \(2\) 的代价消耗两张 \(3\)。
因此先用 \(1\) 消再用 \(2\) 消,最后只剩 \(3\)。
一张或两张 \(3\) 能花费 \(2\) 的代价花完;三张或四张 \(3\) 能花费 \(3\) 的代价花完。
按照平均花费,一定是四张四张花最优,最后再处理余数。
贪心,太困难了!
P11324 【MX-S7-T2】「SMOI-R2」Speaker
题意:每次给出 \(x, y\),查询 \(\max a_x + a_y + a_z - \text{d}(x, z) - \text{d}(z, x)\)。
设 \(p\) 为 \((x, y)\) 路径中距离 \(z\) 最小的点,与 \(z\) 有关的贡献转化为 \(a_z - 2 \times \text{d}(p, z)\)。
设 \(f_p\) 表示 \(\max a_z - 2 \times \text{d}(p, z)\),容易换根 DP 求出。
问题转化为查询 \((x, y)\) 路径中最大的 \(f_p\),倍增 \(O((n + q) \log n)\)。
P10217 [省选联考 2024] 季风
首先有 \(\sum_{i = 1}^m x_i^\prime = X - \sum_{i = 1}^m x_i\)。
我们想让 \(\vert x_i^\prime\vert\) 尽可能小,因此一定存在一直最优方案使得所有 \(x_i^\prime\) 和 \(X - \sum_{i = 1}^m x_i\) 同号。
得到条件成立的一个必要条件:
随便构造一组 \(\sum x^\prime = S_X\) 满足任意 \(\vert x_i^\prime \vert \le k\),然后令 \(\vert y^\prime_i\vert = k - \vert x_i^\prime \vert\)。
此时 \(\sum \vert y^\prime_i\vert\) 不会超过给定 \(S_Y\),否则 \(S_X + S_Y > mk\)。
调整 \(\vert y_i^\prime\vert\) 直到总和满足限制,这只会使 \(\vert x_i^\prime \vert + \vert y_i^\prime \vert\) 越来越小,因此上述条件也是充分的。
把绝对值拆成四个不等式,一个 \(m\) 合法当且仅当任意一个都满足(其中一个是充要的,其他三个顺带满足)。
枚举 \(m \bmod n\),设 \(m = kn + i\)。
分别解四个不等式可以得到合法 \(k\) 的上下界,时间复杂度 \(O(n)\)。
P9755 [CSP-S 2023] 种树
二分答案,设 \(t_i\) 表示 \(i\) 能在规定时间内完成任务的最晚种植时间。
\(t_i\) 越小的越着急被种,按 \(t_i\) 从小到大考虑每个位置。
如果没被种,把他到根的一条链都种上(其他位置 \(t_j < t_i\) 且比 \(i\) 早种,一定满足限制)。
[ARC188A] ABC Symmetry
首先解决判定问题,一个串合法当且仅当 A B C
出现次数的奇偶性相同。
设 \(cnt_{010}\) 表示前缀 \(0 \sim i\) 中 AC
的个数为偶,B
个数为奇的前缀个数。
不难设计一个朴素状态 \(f(i, s, cnt_{000}, \cdots, cnt_{111})\),\(s\) 为前缀 \(i\) 的状态。
\(cnt_{000}\) 产生的合法子串有:\(\binom{cnt_{000} + cnt_{111}}{2}\)。
因此不妨将互补的状态合并,\(f(i, cnt_{000}, cnt_{010}, cnt_{001}, cnt_{100})\),最后一维没必要记录,因为所有 \(cnt\) 的总和确定。
一种更巧妙的方式是 ABC
分别看作 123
,\(s_i\) 为他们的前缀异或和,\((l, r)\) 合法当且仅当 \(s_{l - 1} = s_r\)。
AT_joi2019ho_b
画框从小到大排序,画按美丽度从小到大排序。
第 \(i\) 个画框能放的画的集合包含第 \(i - 1\) 个画框的可选集合,不妨从后往前考虑。
选取能放进第 \(i\) 个画框的且美丽度最大的元素,这样的贪心显然正确。
AT_s8pc_5_e
题意:给定一张包含 #.G
的网格,G
为终点,#
为石砖,.
为冰砖。
冰砖不能转向,石砖能转向。每经过一个石砖走一步的代价增加 \(1\)。
对于所有起点,求出他们到 G
的最短路,\(N, M \le 777, C \le 7777\),\(C\) 为石砖个数。
把所有石砖和终点拉出来建图,总边数 \(O(C)\)。
设 \(f(i, k)\) 表示从点 \(i\) 开始,初始速度为 \(k\),到 G
的最短路,从大到小 DP。
由于最多经过 \(C\) 个石砖,第二维最大 \(C + 1\),时间复杂度 \(O(C^2)\)。
对于每个冰砖 \(i\),找到上下左右最近的石砖 \(j\) 并用 \(f(j, 2) + d(i, j)\) 更新即可。
AT_s8pc_5_f
换种表达描述贡献:从大到小遍历 \(a_i\),如果让 \(i\) 变成 \(0\),继续往下遍历;
否则 \(ans \gets cnt \times a_i\),\(cnt\) 为包含 \(i\) 的区间个数,然后把这些区间删掉。
一旦一个 \(a_i\) 未变成 \(0\) 而是清算了贡献,那么所有询问区间会被分成两半,递归到了子问题。
当前清算完的区间是没有后效性的,这启发我们使用区间 DP:
\(f_{i, k, l, r}\) 表示当前遍历到第 \(i\) 大的数,还剩 \(k\) 次变 \(0\) 机会,所有包含于 \([l, r]\) 的区间贡献和。
如果 \(i \notin [l, r],\ f_{i, k, l, r} = f_{i + 1, k, l, r}\)。
否则根据 \(i\) 变不变 \(0\) 有两种转移,设 \(p\) 为第 \(i\) 大的数的位置:
其中 \(cnt_{l, r, p}\) 表示在包含于 \([l, r]\) 的区间中,包含 \(p\) 的个数。
时间复杂度 \(O(n^5)\)。
P9871 [NOIP2023] 天天爱打卡
把 \((x_i, y_i, v_i)\) 看作右端点为 \(x_i\),长度为 \(y_i\),价值为 \(v_i\) 的线段。
设 \(f_i\) 表示 \(1 \sim i\) 的答案,枚举断点 \(j\),钦定 \(j\) 不打卡,\((j, i]\) 打卡:
其中 \(w_{j + 1, i}\),表示被 \((j, i]\) 包含的线段权值和。
考虑扫描线,在右端点处加入每个线段,设 \(s_i\) 表示当前左端点 \(\le i\) 的权值和:
经典把 \(i, j\) 贡献拆开:
线段树维护 \(g_j = f_{j - 1} - s_j + jd\)。
每加入一个线段 \((l, i, v)\),对应的 \(s_{j \ge l}\) 就要 \(+v\),因此把 \(g_j \sim g_{i - 1}\) 区间 \(+v\)。
注意到一个线段右端点到下一个右端点之间的 \(f\) 值完全相同。
而对于转移用的断点,其一定是某个左端点减一,否则不优。
这启发我们把所有右端点和左端点减一离散化,时间复杂度优化至 \(O(m\log m)\)。
P9754 [CSP-S 2023] 结构体
完全不需要考虑复杂度,直接模拟。
P9119 [春季测试 2023] 圣诞树
对于这种产生交点的情况,走 \(A \to C \to B \to D\) 肯定更优(三角形两边之和大于第三边)。
存在一种最优方案使得路径无交。
因此我们从 \(k\) 开始走,要么顺着该多边形的边往下走,要么走到另一端没走过且离 \(k\) 最近的点。
断环成链,跑区间 DP 即可。
P8817 [CSP-S 2022] 假期计划
枚举 B, C,枚举 B 能到达且 1 也能到达的点作为 A,同样枚举 D。
贪心的取 A 为符合条件的点中价值最大的,但可能出现 A 和 C, D 相等的情况。
枚举 A 为符合条件的点中最大的前三个,这样一定能遍历到最优解,且枚举量降为 \(O(n^2)\)。
P8867 [NOIP2022] 建造军营
边双缩点成一棵树,所有树边都是原图割边。
如果两个边双内部都有点被选,那么其在新树上的路径必须全部被选。
设 \(u\) 内部点数为 \(V_u\),边数为 \(E_u\)。
设 \(f_{u, 0/1}\) 表示在 \(u\) 的子树内,有没有选点的方案数,\(f_{u, 0} = 2^{E_u}\prod_{v \in \text{son}(u)} f_{v, 0}\)。
\(f_1\) 不好转移,考虑加强一下条件:\(f_{u, 1}\) 表示 \(u\) 子树有点被选,且所有被选点到 \(u\) 的边全部被选。
那么 \(f_{u, 1} = (2^{E_u + V_u}\prod_{v \in \text{son}(u)} f_{v, 1} + 2f_{v, 0}) - f_{u, 0}\)。
钦定 \((u, fa)\) 不选,\(ans \gets 2^{n - cnt_u - 1} \times f_{u, 1}\),其中 \(cnt_u\) 表示 \(u\) 子树内的总边数。
本质在被选点集形成的虚树沿着被选边往上延伸到到的最高点 \(u\) 处统计答案。
另一种更自然的统计方法是枚举点集的 LCA(虚树的根),但是转移方程不如上述方法简洁。
P5664 [CSP-S2019] Emiya 家今天的饭
- 被选点集非空。
- 每一行至多选一个点。
- 设选出的总点数为 \(k\),则任意一列被选点数不能超过 \(\lfloor \frac{k}{2}\rfloor\)。
如果只有前两条限制,那么总方案为 \(\prod (s_i + 1) - 1\),其中 \(s_i = \sum a_{i, j}\)。
现在考虑容斥减掉符合前两条但不符合第三条的方案。
注意到 \(2 \times (\lfloor \frac{k}{2}\rfloor + 1) > k\),也就是说非法的列至多一个。
枚举这个非法的列,设 \(f_{i, j, k}\) 表示考虑了前 \(i\) 行,该列放了 \(j\) 个,其他列放了 \(k\) 个的方案数。
将 \(j > k\) 的 \(f_{n, j, k}\) 从答案中减去。
转化一下条件,非法当且仅当 \(j - k > 0\),这样就能把 \(j, k\) 压到一维,单轮复杂度 \(O(n^2)\)。
[ARC104D] Multiset Mean
P11268 【MX-S5-T2】买东西题
[ARC136E] Non-coprime DAG
[ABC163E] Active Infants
[ARC107D] Number of Multisets
P4778 Counting swaps