唐山一中暑假集训 II

Day 6

期望 DP 与 计数 DP

  1. P3734 [HAOI2017] 方案数
    比较有意思的一道题。其实是我随机点开的。
    我们设 \(f_{i, j, k}\) 表示 \(popcount(x) = i\)\(popcount(y) = j\)\(popcount(z) = k\) 的方案数。
    轻松地,我们可以得出 \(f\) 的状态转移方程:\(f_{i, j, k} = \sum_{1 \le x \le i - 1} f_{x, j, k} \times \binom{i}{x} + \sum_{1 \le y \le j - 1} f_{i, y, k} \times \binom{j}{y} + \sum_{1 \le z \le k - 1} f_{i, j, z} \times \binom{k}{z}\)

然后我们设 \(g_i\) 表示从 \((0, 0, 0)\) 走到了第 \(i\) 个障碍物的方案数。
接下来,我们枚举 \(j\) 使得满足题目所定义的包含关系。
我们可以得到:\(g_i = f_{cnt(x_i), cnt(y_i), cnt(z_i)} - \sum f_{cnt(x_i - x_j), (y_i - y_j), (z_i -z_j)}\)
我们把终点视为最后一个障碍物即可。
复杂度 \(O(n^2)\)

  1. P3232 [HNOI2013 / JSOI2013] 游走
    我们把边的期望放在点上。我们考虑 \(E[(u, v)] = \frac{f_u}{deg_u} + \frac{f_v}{deg_v}\)
    然后我们就考虑对于点的期望。
    很显然,我们得到:
    \(f_u = \sum_{v \ne n, (u, v) \in E} \frac{f_v}{deg_v}\)
    如果对于 \(1\) 号点,我们得出:
    \(f_1 = 1 + \sum_{(1, v) \in E, v \ne n} \frac{f_v}{deg_v}\)
    注意到上面这个东西是无向图,所以我们无法直接求解,但可以借助高斯消元的方法求解。

  2. CF1823F Random Walk
    一辈子都想不出来的神秘解法。
    我们还是像上面一样设计状态。但是注意到 \(n \le 10^5\),无法使用高斯消元。
    所以,我们直接设 \(f_u = A_u \times f_{fa} + b_u\)
    我们把这个式子带入到上面的等式当中,我们可以得到:
    \(f_u = \frac{f_{fa}}{deg_{fa}} + \sum \frac{1}{deg_v} (A_v \times f_u + Bv)\)
    移项可得:
    \(f_u - \sum \frac{A_v}{dep_v} f_u = \frac{f_{fa}}{dep_{fa}} + \sum \frac{B_v}{deg_v}\)
    我们注意力惊人,发现对于叶子结点:\(A_u = \frac{1}{deg_{fa}}\)\(B_u = 0\)
    于是上面这个式子就可以从下往上递推。然后再从上向下递推 \(f_u\) 即可。

  3. P6944 [ICPC 2018 WF] Gem Island
    这题神了。
    我们先考虑对于 \(a_1, a_2, ... a_n\) 的方案数。我们得到这样的方案数是 \(\frac{d!}{\prod (a_i - 1)!}\)。同时,我们注意到对于任何一个序列,一共有 \(\prod (a_i - 1)!\) 种分配分裂宝石的方案数。两个乘在一起,我们就发现了每一个的概率时候相等的!
    接下来,我们考虑对于梯形图的情况。很显然,我们设 \(f_{i, j}\) 表示有 \(i\) 个块、当前放了 \(j\) 个的方案数,\(g_{i, j}\) 表示有 \(i\) 个块、\(j\) 个块的权值和。
    然后我们枚举 \(1 \le k \le j - 1\),得到转移方程:
    \(f_{i + k, k} = f_{i, j} \times \binom{j}{k}\)
    \(g_{i + k, k} = \binom{j}{k} \times (g_{i, j} + \min(r, k) \times f_{i, j})\)
    然后没了。

  4. P5664 [CSP-S 2019] Emiya 家今天的饭
    我们考虑容斥。
    我们设 \(f_{i, j, l}\) 表示考虑前 \(i\) 个方案,其中最多的有 \(k\) 个,其它的一共选择了 \(k\) 个。
    然后我们枚举最多的是 \(t\)
    转移:
    \(f_{i + 1, j + 1, k} = f_{i, j, l} \times a_{i, t}\)
    \(f_{i + 1, j, k + 1} = f_{i, j, k} \times (\sum_i - a_{i, t})\)
    \(f_{i + 1, j, k} = f_{i, j, k}\)

注意到 \(j > k\),所以 \(j - k > 0\),所以我们直接把这个压缩成两维即可。令 \(w = j - k\) 进行转移即可。

  1. AT_agc001_e [AGC001E] BBQ Hard

gml:大家看看这个题,就知道为什么 AGC 总爆零了。这就是为什么保证你的代码不超过 1k。

我们考虑组合数的几何意义。我们知道,\(\binom{n}{m}\) 相当于从 \((0, 0)\) 走到 \((n, m)\) 位置的方案数。我们再看看原题的题意:原答案等价于求 \(\sum_{1 \le i \le n} \sum_{i + 1 \le j \le n} \binom{a_i + a_j + b_i + b_j}{a_i + a_j}\)
所以,我们根据几何意义可以得出:这个玩意儿相当于从 \((0, 0)\) 走到 \((a_i + a_j, b_i + b_j)\) 的方案数。所以,我们直接变换一下,相当于从 \((-a_i, -b_i)\) 走到 \((a_j, b_j)\) 的方案数。
所以,我们考虑 DP。我们设 \(f_{i, j}\) 表示从任意一个起点走到 \((i, j)\) 的方案数。但是我们发现这个东西会把自身加上两边,不过这是小问题,只需要减掉即可。最后答案除以 \(2\) 即可。

  1. AT_agc002_f [AGC002F] Leftmost Ball
    我们注意力惊人一下。
    注意到对于任意一个合法的序列,对于任意前缀必须满足的是白色球的数量大于等于出现的颜色种类。
    那么接下来的状态很显然了。我们设 \(f_{i, j}\) 表示有 \(i\) 个白色球,此时有 \(j\) 个颜色。
    首先我们考虑这里放一个白色球。则 \(f_{i, j} = f_{i - 1, j}\)
    接下来我们考虑这里放一个彩色球。注意到此时剩下的位置有 \(n \times k - i - (j - 1) \times (k - 1)\),还有 \(k - 1\) 个这个球,还剩下 \(n - j + 1\) 个颜色供我们选择。所以:\(f_{i, j} = f_{i, j - 1} \times \binom{n \times k - i - (j - 1) \times (k - 1) - 1}{k - 2}\)
    答案就是 \(f_{n, n}\)

  2. P10064 [SNOI2024] 公交线路
    综合了很多技巧。
    首先我们会注意到一个充分必要条件。对于所有的叶子结点,必定存在这些点之间存在连边。这是显然的。
    所以,我们考虑对于路径 \(A\)\(B\)\(C\),假如 \(A \cap B\)\(C \cap C\)\(C \cap A\) 都不是空集,那么 \(A\)\(B\)\(C\) 一定构成了一个连通块。
    我们知道,连通块中存在的数量关系:\(|V| - |E| = 1\),也就是说,点数会比边数多 \(1\)
    然后我们考虑计算方案数:\((|V| - |E|) \times cnt\),其中 \(cnt\) 表示路径集合。
    我们转换视角,考虑对于 \(u\),我们钦定存在恰好 \(j\) 个点满足这些点都不和一个点的联通,所以我们可以考虑容斥。
    我们设 \(f_{u, j}\) 表示点 \(u\) 中存在有 \(j\) 个点不和联通,则 \(f_{u, j} \times 2^{(siz_u - j)(siz_u - k)} \times \binom{cleaf}{k} \to f_{u, j + k}\)
    但是这个复杂度是 \(O(n^3)\),考虑优化。
    我们考虑外面一共有 \(o\) 个点不在这里面,所以我们枚举 \(j\),使得 \((-1)^{j + k} \times f_{u, j} \times 2^{\frac{o \times (o - 1)}{2}} \times 2^{(siz_v - j) \times (siz_o - k)} \times \binom{o}{k}\)。但是,我们发现其中有一些常数,我们提出来后发现剩下的类似于二项式定理,然后直接计算即可。复杂度 \(O(n^2)\)

Day 7

线段树、BIT和单调栈

  1. P3287 [SCOI2014] 方伯伯的玉米田
    考虑 DP。
    我们注意到一个非常优美的性质,每次操作的右端点一定是 \(n\)。注意到这样并不劣。
    我们设 \(f_{i, j}\) 表示 \(i\) 个点,进行了 \(j\) 次操作。所以,我们得到以转移:\(f_{i, j} = \max f_{k, l} + 1\)
    所以,我们注意到满足 \(h_i + j \le h_k + l\)
    注意到这个可以使用二维树状数组优化,复杂度 \(O(nk \log n)\)

  2. CF679E Bear and Bad Powers of 42
    考虑记录区间里面最小需要加上多少可以满足是“坏”数字。
    然后我们考虑操作三,如果最小值小于加上的值,我们就直接操作到叶子结点;
    如果最小值等于加上的值,那么我们重复以上操作;
    如果最小值大于加上的值,也是操作到叶子结点即可。

  3. P5278 算术天才⑨与等差数列
    首先是乱搞方法。
    我们判断一个区间 \([l, r]\) 是等差数列,我们就注意到 \(\max - \min = (r - l) \times k\)。这是一个充分调减。
    同时,我们维护等差数列的二次方和、三次方和、四次方和等等,看你心情,然后 \(O(1)\) 判定即可。
    只要充分条件够多,那么出题人就卡不掉你!
    好了说正解。首先之前那个最大值最小值还是适用,注意到区间中每一个数字 \(x\) 都对于 \(k\) 同余。所以,我们只需要维护差分数组的 \(\gcd\) 即可。

  4. CF609F Frogs and mosquitoes
    首先我们假设 \(x_i < x_j\),如果存在 \(x_i + t_i > x_j + t_j\),那么 \(j\) 无论如何都不会吃到,把它删掉了即可。
    然后维护一个 multiset,每次放进去蚊子,然后我们直接二分青蛙。如果没有被吃掉先存起来,然后如果吃掉了再枚举之前的蚊子即可。最后输出答案。

  5. P6348 [PA 2011] Journeys
    线段树优化建图。
    我们现在开两棵线段树,分别命名为出线段树和入线段树。
    考虑对于出线段树的对应的每一个结点向入线段树的每一个点连边,这样的复杂度是 \(O(\log^2 m)\) 的,并不能通过。
    下面,我们考虑开一个空点 \(u\)。把出线段树的每一个结点向空点连边,边权是 \(1\);入线段树的每一个结点向空节点连边,边权是 \(0\)。这样我们就可以把边的数量降到 \(O(\log m)\) 级别了。
    然后我们注意到跑一次 Dijkstra 的时间复杂度又一次退回到了 \(O(m \log^2 m)\) 的级别,但是由于边权是 \(1\),我们考虑使用 01BFS 进行搜索即可。
    时间复杂度 \(O(m \log m)\)

  6. P4632 [APIO2018] 新家
    非常恶心!超级难写!
    我们先考虑离线做法,然后我们按照时间进行排序。
    然后考虑以坐标为横轴,时间为纵轴,建立平面直角坐标系。
    我们考虑对于 \((t_i, y_i)\),我们维护对于每一个商店的 \(pre_i\) 表示这个商店同类型的前一个商店,这个我们可以使用 set 进行计算。接下来,我们建立线段树,维护的是区间 \([l, r]\) 之间的 \(pre\) 的最小值。
    考虑二分答案,我们二分一下每一个位置,我们发现如果 \([l_i - mid, l_i + mid]\) 之间包含了全部的商店就是合法。这个东西等价于判定 \([l_i + mid + 1, +\infty]\) 之间的所有的 \(pre\) 都大于 \(l_i - mid\)
    注意到这个的时间复杂度还是 \(O(n \log^2 n)\) 的复杂度,现在把这个进行线段树二分即可。

Day 8

线段树合并、线段树分裂、可持久化线段树

  1. P4556 【模板】线段树合并 / [Vani 有约会] 雨天的尾巴
    这是一道板子题。
    选手不需要,也不应该实现 main 函数。
    一眼树上差分,每次在 \(LCA\) 的位置和 \(fa_{LCA}\) 的位置上 \(-1\),在 \(x\)\(y\) 的位置上 \(+1\)
    然后考虑如何处理“同一类型”的操作合并,考虑使用线段树(或许也不需要值域?)。然后我们进行操作之后再跑一次 DFS,再进行 DFS 操作的时候进行线段树合并即可。

  2. P3224 [HNOI2012] 永无乡
    注意到一共有两个操作,第二个操作是经典的区间第 \(k\) 小。
    我们直接考虑如何处理操作二。很明显,我们需要使用可持久化线段树进行维护即可。
    考虑操作一,如果只是联通并且判断连通性的话只需要并查集即可。但是我们需要对于线段树进行合并即可。

  3. P4197 [ONTAK2010] Peaks
    没什么好说的,唤起了曾经的记忆。
    但是我的做法好像没有用到线段树合并?
    我们考虑对于原图建立 kruskal 重构树。然后我们的问题等价于现在 kruskal 重构树上面跳,知道一个节点 \(u\) 的时候我们查询 \(L_u\)\(R_u\) 之间的第 \(k\) 小。
    然后我们考虑使用主席树进行优化即可。
    反正超级难写。

fxr:学长不是 AI,AI 比学长好用。@hypq、@Coding_caopy

  1. P5298 [PKUWC2018] Minimax
    注意到题目最后其实提示到我们这个每一个叶子结点的值都是有概率取到的。
    我们设 \(f_{u, i}\) 表示节点 \(u\) 取到 \(i\) 的概率。
    所以我们得出状态转移方程:

\[f_{u, i} = p_u \times (f_{v1, i} \times \sum_{1 \le j \le i - 1} f_{v2, j} + f_{v2, i} \times \sum_{1 \le j \le i - 1} f_{v1, j}) + (1 - p_u) \times (f_{v1, i} \times \sum_{i + 1 \le j \le m} f_{v2, j} + f_{v2, i} \times \sum_{i + 1 \le j \le m} f_{v1, j}) \]

考虑如何进行优化。我们注意到这个东西的某些是可以使用前缀和或者是后缀和进行优化的。我们考虑维护线段树,线段树节点表示的是 \([l, r]\) 的之间的 \(f_{u, j}\) 的和,然后我们注意到可以使用线段树合并即可。

  1. P6773 [NOI2020] 命运
    听说是 NOI 2020 金牌题的一半?
    我们考虑 DP。设 \(f_{u, i}\) 表示在 \(u\) 节点的情况下,所有限制的起点在 \(u\) 的子树内的限制已经被满足了,剩下的结尾在 \(u\) 的子树内,起点深度最大的是 \(i\) 的方案数。显然的,答案是 \(f_{1, 0}\)
    我们考虑状态转移。我们考虑点 \(v\),对于 \((u, v)\) 这条边:
  • 如果我们选择了这条边,则 \(v\) 中的所有限制自动满足:\(f'_{u, i} = f_{u, i} \times \sum_{0 \le j \le dep_u} f_{v, j}\)

  • 我们不选择这条边,那么这个一定会从 \(u\) 自身转移或者是从 \(v\) 中转移过来。如果从 \(u\) 自身考虑,那么 \(v\) 的深度必须是 \(\le i\) 的;如果从 \(v\) 自身转移的,必须满足 \(< i\)。那么我们得到 \(f'_{u, i} = f_{u, i} \times \sum_{0 \le j \le i} f_{v, j} + f_{v, i} \times \sum_{0 \le j < i} f_{u, j}\)

    然后我们注意到这个可以使用线段树合并进行优化。

我要进国集

  1. P4097 【模板】李超线段树 / [HEOI2013] Segment
    我记得 yaoxi 老师讲过,虽然我对着代码回忆了良久才想起来......
    我们考虑对于区间 \([l, r]\),我们取中点 \(mid\),考虑对于 \(mid\) 这个位置函数值最大的那条线段。
    然后我们考虑插入一条线段。分别比较这条线段所覆盖的位置和现在的状态,然后进行比较即可。
    否则,我们进行 query 的操作。众所周知,在这种情况下,我们考虑 \(y_mid\) 和最后答案所求的位置 \(x\) 进行比较,然后最后返回答案即可。

  2. CF932F Escape Through Leaf
    考虑 DP。我们设 \(f_u\) 表示这个点 \(u\) 跳出这棵树的最小代价。
    那么一定存在:\(f_u = \min f_v + a_u \times b_v\)
    可以把 \(b_v\) 看做斜率,把 \(f_v\) 看做纵截距,把 \(a_u\) 看做当 \(x = a_u\) 的时候的值。
    然后我们注意到这个东西一定是需要结合所有节点的答案的,所以我们执行李超线段树合并即可。

Day 9

树的性质 贪心

  1. P2726 [SHOI2005] 树的双中心
    我们首先考虑枚举每一条边,把这条边断开,然后分别去求剩下的两个子树的中心,计算答案。这显然是正确的。
    此时我们注意到,树的深度 \(h \le 100\),这就启发我们考虑使用复杂度为 \(O(h)\) 计算重心。
    我们考虑 \(siz_u \le 2 \times siz_v\),当且仅当这样的情况下我们才会向这份方向接着走下去。所以我们直接维护每一点的最大、次大儿子即可。

  2. AT_abc362_f [ABC362F] Perfect Matching on a Tree
    挺神的一道题。
    我们考虑如果这个点不是重心,那么一定存在一个 \(v\) 满足 \(siz_v \ge \frac{n}{2}\),所以说必定会存在一个节点 \(t\) 使得这个节点的匹配点还是在这个子树内部,这一定是不优的。
    所以我们考虑设节点 \(r\),满足 \(\sum dis(i, r)\) 最大化。很明显,当 \(r\) 是重心的时候答案最大。如果有奇数个点的话,那么就让 \(r\) 自己不匹配即可。

  3. AT_arc087_d [ARC087F] Squirrel Migration
    可能很简单,但是也没那么简单。
    我们考虑对于一条边 \(w\) 能够经过的次数。明显的,我们知道 \(w = 2 \times \min siz_u, siz_v\)
    同时,我们知道这个距离不是最大距离的充要条件是存在 \(i\)\(p_i\),满足 \(i\)\(p_i\) 在重心的同一棵子树当中。我们考虑容斥,设 \(f_i\) 表示钦定有 \(i\) 个点不满足要求的方案数。
    很明显,\(f_i = \binom{n}{i}^2 \times i!\)
    然后对于这个东西进行树上背包合并即可。

  4. P5666 [CSP-S 2019] 树的重心
    我们考虑对于每一个点进行考虑。
    如果这个点能够成为重心,我们设剩下 \(n - S\) 个点,这个点的最大值是 \(g_v\),这个子树的大小是 \(siz_v\)。那么必须满足以下条件:\(2 \times g_v \le n - S\)\(n - S \le 2 \times siz_v\)
    然后发现这个东西我们可以在进行 DFS 的时候利用树状数组维护即可。

  5. P3320 [SDOI2015] 寻宝游戏
    我们考虑动态维护这个东西。我们按照 DFS 序的方式对于这个进行排序,假设我们现在插入 \(x\),现在左右分别是 \(y\)\(z\),那么答案加上 \(dis(x, y) + dis(x, z) - dis(y, z)\)
    删除同理。可以使用 set 进行维护。

  6. P5327 [ZJOI2019] 语言

  7. P3045 [USACO12FEB] Cow Coupons G
    考虑反悔贪心。
    我们先把前 \(k\) 个优惠券全部使用,然后考虑反悔贪心。我每次向小根堆放进去 \(p_i - c_i\),每次考虑如果这个奶牛我们买不起了,我们是否可以通过调整一下和前面奶牛的关系来买下这只奶牛。这听起来很玄幻,实际上很逆天。但是这是容易并且正确的。

gml:我又失业了。

  1. P2048 [NOI2010] 超级钢琴
    很神的一道题。
    我们维护一个叫做 \(pos, l, r, t\) 分别表示此时的起点是 \(pos\),右端点区间为 \(t\),此时有区间选择的位置似乎 \([l, r]\)。我们每次取出此时的最优解,这个我们可以使用 st 表进行维护。
    每次取出最大值,然后把这个裂开成两个不一样的东西,然后扔到了优先队列即可。

  2. P4364 [九省联考 2018] IIIDX
    首先,我们考虑把 \(a\) 数组从小到大进行排序、
    对于一个点 \(u\),我们可以选择 \(d\) 的充要条件就是存在 \(cnt\) 个还剩下,使得 \(siz_u \le cnt\)。这是明显的。我们考虑使用线段树维护现在还剩下的东西的个数,这样我们只需要在线段树上进行线段树二分即可。

  3. CF725F Family Photos
    我们使用临项交换法。
    我们考虑第一开始的四个分别是 \(a1\)\(a2\)\(b1\)\(b2\)
    我们考虑,:

  • 如果 \(a1 + b1 \ge a2 + b2\)
    我们通过分析可知,先手、后手不论如何都会选择第一张照片;
  • 如果 \(a1 + b1 < a2 + b2\),且 \(a1 > b2\)
    我们知道对于两个人还是不会选择第一个,但是如果没有手段的话一定会选择;
  • 如果 \(b1 > a2\)
    那么我们一定满足取的是 \(a2 - b1\)
  • 最后,我们剩下的那个情况我们知道两个人都不会选择这个情况。

Day 10

交互 构造 通信

选手不需要,也不应该实现 main 函数

  1. P11240 [KTSC 2024 R2] 回文判定
    我们注意到 \(B \le 1\),所以这个强大的东西只能够询问 \(1\) 次。
    我们考虑从 \(i \in [1, \frac{n}{2} - 1]\),每次询问 \(0, i, n - i - 1\) 这个东西。如果返回值是 \(3\),则相安无事;如果是 \(0\),那就直接玩完;如果是 \(1\),我们就考虑接着比较。
    在最后,我们每次 check 一下,比较 \(0, n - 1, i\) 这些位置即可。细节有点多。

  2. P16434 [APIO 2026 中国赛区] 蛋糕
    我们一个 subtask 一个 subtask 看。
    对于 subtask2,我们考虑询问 \({d, 100, 102}\) 这个东西即可;
    对于 subtask3,我们注意到 \(2^K = W\),所以我们就可以对于这个东西考虑进行二进制,最后再使用二进制进行维护即可;
    最后我们来看 subtask4,我们注意到 \(3^K \ge W\),所以我们考虑判断 \(d\) 是属于现在的哪个区间里面的,可以发现我们每次取出一个部分的左右两边的数字加在一起,判断大小。注意到有且仅有所存在的那个位置会和另外的位置不一样,所以这就做出来了。

  3. CF1835C Twin Clusters
    听说这题可以乱搞?
    我们从高位向低位考虑,如果这个位置是 \(k\),那么这个的权值是 \(2^k\)。那么,一定会存在一个位置 \(k\),满足前 \(k\) 个位置中存在 \(2^k + 1\) 个。我们根据鸽巢原理得到这样一定存在重复。

  4. P8376 [APIO2022] 排列
    我们考虑每次放入最大值,如果我们放在第一个位置,那么答案会贡献 \(ans \leftarrow ans + 1\);如果我们考虑把这个放在最后一个位置,那么答案就会贡献 \(ans \leftarrow ans \times 2\) 的权值。
    我们注意到这个的长度是 \(2 \times \log k\) 的。还是不够,我们接着进行优化。
    我们注意到每次答案加上一太慢了,所以我们考虑能否进行一些更快的操作。如果我们此时把最大值放在第三个位置,那么答案会贡献的是 \(ans \leftarrow ans + 3\)。这是很不错的。所以我们递归判断即可。

  5. AT_agc027_d [AGC027D] Modulo Matrix
    我们对于整个图进行黑白染色。我们不妨钦定 \(\max\) 的都是黑色点,\(\min\) 的都是白色点。这是显然的。
    我们考虑如果 \(m = 1\)。然后我们考虑一个黑色点周围的所有白色点分别是 \(a\)\(b\)\(c\)\(d\),那么这个位置的一个合法答案就是 \(a \times b \times c \times d + 1\)。此时我们希望这些都是质数。
    接下来,我们注意到这样需要 \(O(n^2)\) 个质数。这显然是不行的。我们充分发扬人类智慧,对于每一条斜线上面的所有点设置成为质数。这样我们只需要让每一个点是这个斜线上面的点的倍数即可。

posted @ 2026-08-01 10:07  Bob1108  阅读(29)  评论(1)    收藏  举报