【游记】2022寒假游记

2022.1.16

\(\cdot\) #\(\text{6067}\)

单调栈模板题,直接用单调栈维护即可。

\(\cdot\) #\(\text{6068}\)

题意很奇怪,大意是给出一个长度为 \(n\) 的序列和 \(m\) 个区间,
对于第 \(i\) 个区间 \(l_i\),\(r_i\),求\(a_{l_i-1} \leqslant \max\limits_{i=l_i}^{x-1}a_i \leqslant a_x \bigg(x \in \left[l_i+1,r_i\right]\bigg)\)的数量。

也就是给出左右两个区间端点,求满足以下条件的子区间的个数:

  1. 子区间的左端点为原区间左端点;

  2. 子区间的长度不小于 3;

  3. 子区间左右端点之间每一个数都严格比子区间左端点的值大;

  4. 子区间左右端点之间每一个数都严格比子区间右端点的值小。

设向右比第 \(i\) 个数大的数的位置为 \(p_i\) ,则显然当 \(p_{l-1} > r\) 时贡献为0。

反之求出第 \(l\)\(r\) 个数中最大的数的位置,记为 \(pos\),则显然 \(pos\) 是所有合法的子序列中右端点最靠右的。

可知答案为 \(p_i\),\(p_{p_i}\),\(p_{p_{p_i}}\),\(\cdots\),\(pos\) 的个数。

因为此答案靠前的元素可以视作为 “ 拼接 ” 在考后的元素前,所以不妨设 \(f_i\) 为从第 \(i\) 个数开始 \(p_i\),\(p_{p_i}\),\(p_{p_{p_i}}\),\(\cdots\) 的个数。

因此 \(f_{n+1} = 0\)\(f_{i} = f_{p_i}+1\)

所以答案为 \(f_{p_i}-f_{pos}+1\)

\(\cdot\) #\(\text{6069}\)

首先计算出在每一个位置上最多能往上延伸的 1 的个数 \(a_{i,j}\)

然后将每一个点向左右拓展,分别找到其左侧和右侧第一个比 \(a_{i,j}\) 小的数的位置(也就是保证 \(a_{i,j}\) 为区间最小值),分别记为 \(l_{i,j}\) , \(r_{i,j}\)

那么这一个点对答案的贡献即为 \((r_{i,j}-l_{i,j}-1)\times a_{i,j}\)

真的是 \((r_{i,j}-l_{i,j}-1)\times a_{i,j}\) QAQ

\(\cdot\) #\(\text{6070}\)

几乎是上一题的一维版本,只是转移方程变成了 \((sum_{r-1}-sum_l)\times a_i\)

\(\cdot\) #\(\text{6071}\)

数据有锅被先辈掉了,但是写了两道洛谷上相似的题目。

\(\cdot\) #\(\text{6072}\)

滑动窗口模板题,直接用单调队列维护即可。

\(\cdot\) #\(\text{6073}\)

上一题的二维版本,降维即可。

\(\cdot\) #\(\text{6074}\)

我见过的唯一一个哈夫曼编码题

思路与合并果子相似,每一次选择权值最小的前 \(k\) 个字符(不足 \(k\) 个则全部合并,直到无法合并为止),合并累加贡献后重新放入大根堆中继续合并。


2022.1.17

\(\cdot\) \(\text{P1901}\)

用单调栈维护两端第一个比当前发射塔高的发射塔并计算贡献即可。

\(\cdot\) \(\text{P1950}\)

是 #\(\text{6069}\) 的计数版本,只有转移方程有区别。

\(\cdot\) \(\text{P3194}\)

本蒟蒻不会用计算几何QAQ

首先读入 \(n\) 个一次函数,以斜率为第一关键字,截距为第二关键字从大到小排序。

然后维护单调栈,跳过斜率相同且截距较小的一次函数(因为它们对答案没有贡献),然后重复计算当前函数与栈顶函数交点的横坐标,是的栈中相邻两个函数的交点的横坐标单调递减。

最后在维护单调栈的同时计算答案,在处理完所有一次函数后按编号从小到大排序输出即可。

\(\cdot\) \(\text{P1776}\)

明明二进制可以切为什么用单调队列?

多重背包问题模板,大致是对于每一个物品枚举一次背包大小对物品体积的余数,对于每一个余数进行单调队列优化,根本听不懂QAQ

\(\cdot\) \(\text{P2254}\)

显然有 \(O(nmt)\) 的做法,但是不够优,因此考虑优化至 \(O(nmk)\)

\(f_{tim,i,j}\) 为在第 \(tim\) 段时间内,最终到达点 \((i,j)\) 的滑行最长距离。

显然,对于第 \(tim\) 段时间 \([s_{tim},t_{tim}]\) , 设它的长度为 \(len_{tim} = t_{tim}-s_{tim}+1\) , 则这一段时间滑行的距离只能为 \([0,len_{tim}]\) ,所以可以用单调队列维护。

最后再在维护单调队列的时候特判障碍物和边界即可。

\(\cdot\) \(\text{P4779}\)

\(Dijkstra\)堆优化模板题,ctj 即可

\(\cdot\) \(\text{P1484}\)

首先显然有 \(DP\) 做法,但是不够优,考虑线性做法。

对于第 \(i\) 棵树,有两种策略:

  1. 取第 \(i\) 个点。

  2. 取第 \(i-1\) ,\(i+1\) 个点。

于是可以得到以下算法:维护小根堆和双端队列,将所有点
存入小根堆中,每次取最大值 ,记其位置为 \(i\) , 则再双端队列中将点 \(i-1\) , \(i+1\) 删除,并将点 $ {a_{i-1}+a_{i+1}-a_i,i}$ 存入小根堆并记录贡献。

据说准确性来自最大流,根本听不懂QAQ

\(\cdot\) \(\text{P2596}\)

太蒻了不会切QAQ


2022.1.18

\(\cdot\) \(\text{P3367}\)

并查集模板题,用朴素并查集维护即可。

\(\cdot\) \(\text{P5937}\)

算法:种类并查集根本不会写

读入后将各区间左右端点离散化,依次处理。

定义 \(len\) 为离散化后的区间总长度,对于每一个区间 \([l_i,r_i]\),开两倍数组,其中\(find(l_i) = find(r_i+len)\)\(find(l_i+len) = find(r_i)\) 表示奇数区间, \(find(l_i) = find(r_i)\)\(find(l_i+len) = find(r_i+len)\) 表示偶数区间。

那么根据给出的区间类型判断是否相悖即可。

\(\cdot\) \(\text{UVA11987}\)

同题目,此题和朴素并查集已经十分接近了。

难点在于维护第二种操作:把 \(p\) 移动到 \(q\) 所在的集合。

考虑开两倍数组,建“虚点”,定义下标为 \(i\) 的点所对应的虚点下标为 \(i+n\)

对于第一种操作,将“虚点”合并即可。

对于第二种操作,将原点直接连接到所给“虚点”上即可。

\(\cdot\) \(\text{P2024}\)

\(\text{P5937}\) 很相似,开三倍数组。

第二种错误很好判断。

对于第一、第三种错误,根据命题处理,算法如下:

  1. 对于 \(X\)\(Y\) 是同类的命题:

    1.1 如果 \(\begin{matrix}\underbrace{find(X) = find(Y+N)}\\{Y\text{吃}X}\end{matrix}\) 或者 \(\begin{matrix}\underbrace{find(X+N) = find(Y)}\\{X\text{吃}Y}\end{matrix}\) ,则说明此命题为假命题。

    1.2 如果在 1.1 中证明此命题为真命题,则合并:

    \(\begin{matrix}\underbrace{(X,Y)\text{,}(X+N,Y+N)\text{,}(X+N\times2,Y+N\times2)}\\{X\text{是}Y\text{的同类}}\end{matrix}\)

  2. 对于 \(X\)\(Y\) 的命题:

    2.1 如果 \(\begin{matrix}\underbrace{find(X) = find(Y)}\\{X\text{是}Y\text{的同类}}\end{matrix}\) 或者 \(\begin{matrix}\underbrace{find(X) = find(Y+N)}\\{Y\text{吃}X}\end{matrix}\) ,则说明此命题为假命题。

    2.2 如果在 2.1 中证明此命题为真命题,则合并:

    \(\begin{matrix}\underbrace{(X+N,Y)\text{,}(X+N\times2,Y+N)\text{,}(X,Y+N\times2)}\\{X\text{吃}Y}\end{matrix}\)

于是就可以愉快地切题了此题还可以用权值并查集维护。

记 0 为两者是同类,1 为前者吃后者,2 为后者吃前者。

设每次操作时给出的两只动物分别为 \(a\)\(b\) , 其父亲分别为 \(f_a\)\(f_b\) , 关系分别为 \(res_a\)\(res_b\) , 则具体操作如下:

判断 \(a\)\(b\) 是否为同类: 判断 \(res_a = res_b\) 是否成立;

判断 \(a\) 是否吃 \(b\) : 判断 \(res_a -res_b+3 \equiv 1 \pmod 3\) 是否成立;

合并同类 \(a\)\(b\)\(res_{f_a}\) 设为 \(res_b-res_a+3 \bmod 3\)

合并捕食者 \(a\) 和猎物 \(b\)\(res_{f_a}\) 设为 \(res_b-res_a+4 \bmod 3\)

并查集路径压缩代码如下:

int find(int x)
{
	int now = f[x];
	if(f[x] == x) return x;
	f[x] = find(f[x]);
	res[x] = (res[x]+res[now])%3;
	return f[x];
}

\(\cdot\) \(\text{P3420}\)

直接全部砸掉不就完了?

按照题意合并存钱罐与钥匙所在的存钱罐,最后计算连通块即可。

\(\cdot\) \(\text{P3465}\)

在图中找任意一棵生成树,再在非树边中找出任意一条返祖边,\(DFS\)
计算答案即可。

\(\cdot\) \(\text{P3631}\)

直接输出 0 骗了 30 分。

这道题第一眼看上去和并查集没有太多关系,所以我们先找规律:

| \(A\) | \(C\) | \(E\) | \(G\) | \(I\) |
| :----------: | :----------: | :----------: | :----------: | :----------: | :----------: | :----------: |
| \(B\) | \(D\) | \(F\) | \(H\) | \(J\) |

\(\because A \bigotimes B \bigotimes C \bigotimes D = 1\)

\(\quad C \bigotimes D \bigotimes E \bigotimes F = 1\)

\(\therefore A \bigotimes B = E \bigotimes F\)

\(\therefore A \bigotimes B \bigotimes E \bigotimes F = 0\)

进而可知:

\(A \bigotimes B \bigotimes G \bigotimes H = 1\)

\(A \bigotimes B \bigotimes I \bigotimes J = 0\)

\(\cdots\cdots\)

\(a_{i,j} \bigotimes a_{i+1,j} \bigotimes a_{i,k} \bigotimes a_{i+1,k} = \begin{cases}0 & k-j\equiv0\pmod{2} \\ 1 & k-j\equiv1\pmod{2}\end{cases} (k > j)\)

再看:

\(A\) \(B\)
\(C\) \(D\)
\(E\) \(F\)
\(G\) \(H\)
\(I\) \(J\)

\(\because A \bigotimes B \bigotimes C \bigotimes D = 1\)

\(\quad C \bigotimes D \bigotimes E \bigotimes F = 1\)

\(\therefore A \bigotimes B = E \bigotimes F\)

\(\therefore A \bigotimes B \bigotimes E \bigotimes F = 0\)

进而可知:

\(A \bigotimes B \bigotimes G \bigotimes H = 1\)

\(A \bigotimes B \bigotimes I \bigotimes J = 0\)

\(\cdots\cdots\)

\(a_{i,j} \bigotimes a_{i,j+1} \bigotimes a_{k,j} \bigotimes a_{k,j+1} = \begin{cases}0 & k-i\equiv0\pmod{2} \\ 1 & k-i\equiv1\pmod{2}\end{cases} (k > i)\)

所以由上归纳可知:

\(a_{1,1} \bigotimes a_{x,1} \bigotimes a_{1,y} \bigotimes a_{x,y} = \begin{cases}1 & x\equiv0\pmod{2}\ \cap \ y \equiv0\pmod{2} \\ 0 & x\equiv1\pmod{2}\ \cup \ y\equiv1\pmod{2}\end{cases} (x > 1,y > 1)\)

于是可以得知当一个矩阵的第一行与第一列确定时,此矩阵确定。

考虑枚举点 \(a_{1,1}\) 的取值,于是对于每个已染色的点 \((x,y)\) ,都可以确定 \(a_{x,1} \bigotimes a_{1,y}\) 的值,也就是确定 \(a_{x,1} = a_{1,y}\)\(a_{x,1} \ne a_{1,y}\) ,考虑用带权并查集维护关系。

当我们判断矩阵合法后,只需累加 \(2^{\text{连通块个数-1}}\) 即可。

肝了几个小时,还写出两份不同的 AC 代码...

\(\cdot\) \(\text{P5227}\)

承接前面 \(\text{P3420}\)\(\text{P3465}\) 的思路,考虑将原图划分为一棵树和若干棵非树边。

那么当且仅当一个节点通向它的父节点的边与所有和他相邻的非树边被删除时,原图变得不连通。

考虑将每一条非树边附上一个随机的权值 \(rnd_i\) ,树边的权值记为与它相邻的所有非树边的异或和,那么在理想情况下,对于每一个询问只需要判断是否存在一个子集使其所有元素的异或和为 0 即可。


2022.1.19

\(\cdot\) \(\text{P3372}\)

DZY爆切黄题!

\(\cdot\) \(\text{P3373}\)

DZY爆切绿题!

\(\cdot\) \(\text{P1382}\)

扫描线模板题。

将每一个矩形的左右端点离散化,分别记为 \(l_i\) , \(r_i\)

\(a_j\) 设为 \(\max(a_j,h_i) (l_i \leqslant j < r_i)\) , 用线段树维护。

最后模拟计算结果即可。

\(\cdot\) \(\text{P1295}\)

我喜欢暴力,所以这道题我用快读 + O2 + 二维 DP 过了...

\(\cdot\) \(\text{P5459}\)

此题用朴素线段树可以 AC ...

考虑用前缀和优化,对于合法的 \(sum_{l-1}\)\(sum_r\) ,必有 \(L \leqslant sum_r - sum_{l-1} \leqslant R \ (l < r)\)

\(\therefore sum_r-R \leqslant sum_{l-1} \leqslant sum_r - L \ (l < r)\)

所以只需要用朴素线段树维护对于每个 \(r\) 有多少个 \(l\) 满足上式即可。


2022.1.20

\(\cdot\) #\(\text{6082}\) / \(\text{P4041}\)

给定一组操作和若干个数,求操作后每个数的值。

操作有加法,减法,乘法, 加法 和去大值,去小值。

考虑将每一个数按大小排序,单点修改立刻转换为序列全局修改。

加法,减法和乘法都很好维护,加法 下传操作给定相加的个数也可以维护。

对于去大值和去小值,因为无论如何修改,序列恒递增,所以用线段树维护区间最大值和最小值,维护一个 \(set\) 标记即可。

优先级: $set < mul < \text{add} = add $

\(\cdot\) #\(\text{6083}\) / \(\text{CF718C}\)

艹,改了一个学期终于过了...

维护一个序列,满足区间加和求 \(\sum\limits_{i = l}^r f(a_i)\) 的值。

\(f(1) = f(2) = 1,f(i) = f(i-1)+f(i-2) \ (i \geqslant 3)\)

正常维护 \(a_i\) 的值貌似不行,考虑用矩阵快速幂,直接维护矩阵。

然后上传、下传的标记同样设为矩阵即可。

\(\cdot\) #\(\text{6084}\)

还没有写 QAQ...

维护一个序列,满足区间修改和求区间最大子段和。

怎么把求区间最大子段和转化为满足区间加法的操作呢?

考虑理想情况,首先,区间最大子段和显然至少等于:\(\max (lson_{\texttt{最大子段和}},rson_{\texttt{最大子段和}})\)

那么不包含在上述讨论情况的贡献只有:跨越左儿子和右儿子的最大子段和。

考虑将其分解为 \(lson_{\texttt{后缀最大值}} + rson_{\texttt{前缀最大值}}\)

前缀最大值等于: \(\max(lson_{\texttt{前缀最大值}},lson_{sum}+rson_{\texttt{前缀最大值}})\)

后缀最大值等于: \(\max(rson_{\texttt{后缀最大值}},rson_{sum}+lson_{\texttt{后缀最大值}})\)

于是此题就可以用线段树维护了。

求珂朵莉树解法 ...

\(\cdot\) #\(\text{6085}\) / \(\text{CF413E}\)

此题的思想比较巧妙。

察♂觉♂到此题只有二维,考虑一维维护。

于是想到用二向箔线段树维护。

维护每个区间左上角到右上角、左上角到右下角、左下角到右上角、左下角到右下角的最短路径。

此时维护的信息和转移满足线段树的使用约束,于是用线段树维护即可。

\(\cdot\) \(\text{P2605}\)

DZY爆切黑题 ...(bushi)

\(\cdot\) #\(\text{4373}\) / \(\text{P5278}\) / \(\text{P3792}\) \(\texttt{加强版}\)

出题人非常的聪明,至少和算术天才⑨一样聪明 ...

思路一:正解

一个以 \(k\) 为公差,\(l\),\(r\)为左右端点的等差数列存在当且仅当它满足以下几个条件:

  1. \(\max - \min = (r-l)\times k\)

  2. \(\gcd\limits_{i = l}^{r-1} a_{i+1}-a_i = k\)

  3. \(a_i \ne a_j (i \ne j)\)

于是维护的信息有:

\(\max_{\texttt{区间}} \ \min_{\texttt{区间}} \ \max_{pos_{a_i}} \ val_l \ val_r \ \gcd_{\texttt{区间相邻两项的差}}\)

思路二:♂乱♂搞♂

利用哈希思想,构造一个仅与序列中的项相关的哈希函数。

想到方差,\(s^2 = \sum\limits_{i = l}^r(a_i-\overline{a_{\text{l,r}}})\)

于是维护方差即可。

思路三:♂搞♂爆♂了♂

本蒟蒻在课上提出维护 \(\sum\limits_{i = l}^ra^p\) 的哈希函数,得到了老师的认可并推荐我们自己去 \(\texttt{van}\) ♂。

结果被我在题解里翻到了 ...

设常数 \(p = 2\) ,则有下式:

\[\operatorname{hash}(i) = \sum\limits_{i = 0}^{n-1}(x+i\times k)^2 \]

将右式展开,可得:

\[\operatorname{hash}(i) = \sum\limits_{i = 0}^{n-1}(x^2 + 2 \times x \times i \times k + i^2 \times k^2) \]

\[\therefore \operatorname{hash}(i) = n \times x^2 + 2 \times x \times k \times \sum\limits_{i = 0}^{n-1}i + k^2 \times \sum\limits_{i = 0}^{n-1}i^2 \]

由小学奥数可知:

\[\sum\limits_{i = 1}^ni^2 = \dfrac{n \times (n+1) \times (2 \times n + 1)}{6} \]

再选择大模数维护哈希函数即可。比如 114514 和 308379 比如 \(1e9+7\)\(1e9+9\)

我真聪明 ...


2022.1.21

\(\cdot\) \(\text{P3374}\)

♂爆♂切♂...

\(\cdot\) \(\text{P3368}\)

♂切♂爆♂了♂...

\(\cdot\) \(\text{P3372}\)

是不是好像重题了 ...

\(\cdot\) #\(\text{6079}\) / \(\text{CF652D}\)

把每一个线段按右端点 \(r_i\) 从小到大排序,那么只需要考虑当前线段之前有多少条线段满足 \(l_i \leqslant l_{now}\) ,树状数组维护即可。

\(\cdot\) #\(\text{6080}\) / \(\text{P1972}\) / \(\text{SP3267}\)

古人类智慧题 ...

在线维护十分困难,考虑离线维护。

首先将每一个查询按右端点 \(r_i\) 从大到小排序。

\(a_i\)\(1\)\(i\) 中不重复的元素个数。

但是会出现重复减去无关的的贡献。

那么只要每次遇到一个数时,把这个数上一次出现的位置的贡献减去即可。


2022.1.23

\(\cdot\) \(\text{P3379}\)

LCA 模板题。

\(\cdot\) \(\text{P3128}\)

树上差分基础题。

对于从 \(a\)\(b\) 的一条路径,设差分数组为 \(f_i\) ,父亲节点为 \(fa_i\) 则:

\[f_a+1 \]

\[f_b+1 \]

\[f_{\operatorname{lca(a,b)}}-1 \]

\[f_{fa_{\operatorname{lca(a,b)}}}-1 \]

\(\cdot\) \(\text{P6869}\)

对于从 \(a\)\(b\) 的一条路径,设差分数组为 \(f_i\) ,则:

\[f_a+1 \]

\[f_b+1 \]

\[f_{\operatorname{lca(a,b)}}-2 \]

\(\cdot\) \(\text{P5021}\)

此题显然需要二分答案,二分最短的赛道长度为 \(mid\)

从下向上 \(DFS\) ,对于每一个节点,把所有从其子树来的链进行处理,设长度为 \(len\)

  1. \(len \geqslant mid\) 时,累计贡献。
  2. \(len < mid\) 时,将 \(len\) 存入一个 \(multiset\) 中。

对于 \(multiset\) 中的每一条链,尝试两两配对。如果配对长度可以不小于 \(mid\) 则累计贡献,否则将无法配对成功的链中最长的一条上传给父节点。

\(\cdot\) \(\text{P4408}\)

先求出树的一条直径,再暴力枚举每一个点计算贡献即可。


2022.1.24

\(\cdot\) \(\text{P3258}\)

久违树状差分。

对于从 \(a\)\(b\) 的一条路径,设差分数组为 \(f_i\) ,则:

\[f_a+1 \]

\[f_b+1 \]

\[f_{\operatorname{lca(a,b)}}-2 \]

但是值得注意的一点是:除了起点外,其它点的答案都要减一。

\(\cdot\) \(\text{P6374}\)

此题需要分类讨论。

给出 \(a\)\(b\)\(c\) 三个点,设 \(n\) 为节点总数量, \(d = \operatorname{lca(a,b)}\)\(\operatorname{f(a,b)}\)\(a\)\(b\) 的路径中与 \(b\) 相邻的节点的子树大小 \((\operatorname{lca(a,b)} = b)\)\(\operatorname{siz(a)}\)\(a\) 的子树大小。

  1. \(c = d\) 时,答案为 \(n-\operatorname{f(a,c)}-\operatorname{f(b,c)}\)
  2. \(c\)\(a\)\(d\) 的路径上时,答案为 \(\operatorname{siz(c)}-\operatorname{f(a,c)}\)
  3. \(c\)\(b\)\(d\) 的路径上时,答案为 \(\operatorname{siz(c)}-\operatorname{f(b,c)}\)
  4. 如果前三个命题均不成立,则无解,答案为 \(0\)

\(\cdot\) \(\text{P3384}\)

树剖模板题。

分两次 \(DFS\)

第一遍求出 \(f\) (父亲节点) , \(siz\) (子树大小) , \(dep\) (节点深度) ,\(son\) (重儿子) 。

第二遍求出 \(top\) (重链顶) , \(id\) (新编号) , \(rnk\) (对应旧编号) 。

对于链上加和链上求和,按照轻重链依次对路径上的每一个重链操作。

对于子树加和子树求和,按照 \(DFS\) 序进行区间操作即可。

\(\cdot\) \(\text{P3899}\)

此题涉及到子树内的树上差分。

给出 \(a\)\(k\) ,求出所有 \(a\)\(b\)\(c\) 的祖先,\(a\)\(b\) 的距离不超过 \(k\) 的有序点对 \((a,b,c)\)

\(b\)\(a\) 的祖先时,答案可以 \(O(1)\) 求出。

\(a\)\(b\) 的祖先时,提供一种离线算法:

用树状数组记录以深度为下标的贡献,记 \(f_i\) 为深度不超过的 \(i\) 的节点贡献。

\(DFS\)\(a\) 时,记 \(x_a\)\(f_{dep_a+k}\)

\(DFS\)\(a\) 为根的子树后,记 \(y_a\)\(f_{dep_a+k}\)

则答案 \(ans_a = y_a - x_a + \min(dep_a,k) \times (size_a-1)\)


2022.1.25

\(\cdot\) \(\text{P1119}\)

太久没有打 Floyd 都忘光了 ...

按照村庄修复的时间跑 \(Floyd\) ,处理询问。

因为村庄修复的时间和询问的时间都不递减,所以可以直接更新。

\(\cdot\) \(\text{P1144}\)

朴素 \(Dijkstra\) + 判断最短路数量即可。

\(\cdot\) \(\text{P3063}\)

题目中的两个变量相悖,所以不能直接维护。

考虑枚举容量的最小值 \(mid\) ,每一次 \(Dijkstra\) 忽略容量小于 \(mid\) 的边,更新答案即可。

\(\cdot\) \(\text{P1462}\)

同上题,因为数据比较大,剩余血量与收费最大值又具有单调性,考虑二分答案 \(mid\) ,计算能否存活即可。

\(\cdot\) \(\text{P5201}\)

最短路树是什么?

因为题目中给定的最短路唯一,考虑建最短路树。

对于 \(u\)\(v\) ,当 \(dis_u + w_{u,v} = dis_v\) 时,边 \((u,v)\) 在最短路树上。

建树后,记录每个子树的大小 \(siz_i\) 则以 \(x\) 节点为根的子树连到 \(1\) 号节点的贡献为 \((dis_x-t) \times siz_x\)

\(DFS\) 时取最大值即可。

posted @ 2022-01-31 23:58  Daniel2020  阅读(41)  评论(0)    收藏  举报