做题(部分)笔记(2021.03.15~2021.04.11)
P3225 [HNOI2012]矿场搭建
做法一:直接双连通分量缩点然后求叶子节点个数,但是没必要
做法二:考虑算出所有割点后割掉割点把图分裂成几块。设 \(c\) 代表每一块和多少个前割点相连。\(c=0\) 代表这是一个独立的连通块,需要从里面选两个点作为出口;\(c=1\) 需要从里面选择一个点作为出口;\(c=2\) 的话无论割掉哪个点都有一种方法走到别的地方去,所以不需要放点。(显然地,别的块一定存在 \(c=1\) 的情况, 否则这些点就不是割点了
code: https://www.luogu.com.cn/record/47839628
CF1472G Moving to the Capital
傻逼题。首先 BFS 处理出 \(d\) 数组。然后考虑 DP。有一个微小的 observation。走 \(d_u\ge d_v\) 的边一定在最后走。因为普通每走一步 \(d\) 必然递增,如果我们在走完 \(d_u\ge d_v\) 的边后就不走了一定比再继续走要更优。由于本题规定转移一定要满足 \(d_u<d_v\),所以可以直接 dfs 去 DP。\(f(u)=\min_v\{\min(f(v),d(v))\}\)。
code: https://codeforces.com/contest/1472/submission/109982296
CF1394B Boboniu Walks on Graph
注意到我们每一个 C 对应的边集会组成一个出度为 1 的图;又因为每个点都能到达自己,所以一定是很多个环,即每个点入度也为 1,即每个点的出度点构成的集合为全集。预处理出每一个位置的 \(k\) 代表着哪几个点被连到的集合,我们可以用集合哈希来判断集合相等。
code: https://codeforces.com/contest/1394/submission/109985058
CF1450E Capitalism
用差分约束即可。
https://codeforces.com/contest/1442/submission/110467979
3.17 CX 测验
3道模板题,阿克
P3267 [JLOI2016/SHOI2016]侦察守卫
考虑 DP。\(g(u,i)\) 表示子树内部以 \(u\) 中心 \(i\) 为半径的点没被覆盖的情况;\(f(u,i)\) 则表示 \(u\) 被覆盖且还要覆盖节点上方 \(i\) 的情况。下角标代表算到第几个儿子。
然后还要更新一下 \(f\) 和 \(g\)(\(f(u,i)\leftarrow f(u,i+1), g(u,i)\leftarrow g(u,i-1)\))
https://www.luogu.com.cn/record/48007984
P4365 [九省联考2018]秘密袭击coat
题意:问所有连通块的权值 \(k\) 大点的权值和。
考虑枚举 \(k\) 大点 \(u\)。求出有多少个连通块包含 \(\ge k\) 个 \(\ge w_u\) 的点。考虑用树上背包问题求解。\(f(u,i)\) 表示以 \(u\) 为根的子树中有 \(\ge i\) 个 \(\ge w_u\) 个点的方案数。复杂度 \(O(n^2w)\)。
考虑疯狂剪枝。首先要严格控制好树上背包的各种上界;然后对于如果 \(\ge w_u\) 的点个数 \(\ge k\) 那么就直接不要计算了;然后就可以过去了(
CF1442C Graph Transpositions
考虑我们使用图翻转有两个作用,要么是为了节省距离,要么是被迫使用。我们考虑由于 \(2^k\) 在 \(k>18\) 的时候就超过了 \(200000\),即 \(k>18\) 的时候使用只有可能是因为被迫为了抵达终点而使用。所以我们先做一次 \(k\le 18\) 的分层图 BFS 最短路,然后如果发现仍然无法抵达终点,我们不停地 \(k:=k+1\),每加一次就将图扩展一层,然后跑最短路。为了优化,每一层把更新的点推进队列中传给下一层。
https://codeforces.com/contest/1442/submission/110467979
P6255 [ICPC2019 WF]Dead-End Detector
考虑两种不同的情况。
- 连通块是一棵树
在每个度为 1 的节点处装上即可
- 连通块不是一棵树
那么 \(s\to t\) 是 non-rebundant dead-end 当且仅当割掉这条边后 \(t\) 所在的连通分量是树且 \(s\) 是环上点(否则是 rebundant)。
我们找到所有环上点(用拓扑排序)即可。
https://www.luogu.com.cn/record/48127776
AtCoder Beginner Contest 196
这场够毒瘤的
https://www.luogu.com.cn/blog/forever-captain/atcoder-beginner-contest-196-ti-xie
P5999 [CEOI2016]kangaroo
考虑我们第 \(i\) 个数插在哪里。一开始我们只有一个 \(1\)。设计状态 \(f(i,j)\) 表示已经填入了 \(1\dots i\),此时已经填的数形成了 \(j\) 个连续段。对于转移,要么它连接两个连续段;要么它新开一个连续段。不能只接在一个连通块上,这样会导致后面更大的数插入到这里后出现问题。
-
新开连续段。此时的贡献为 \(j\times f(i-1,j-1)\)。注意要特判当 \(i > s\) 或者 \(j < s\) 那么前面的系数不是 \(j\) 而要减去 \(1\) 或者 \(2\)。
-
连接两个连续段。此时要考虑连接哪两个连续段。此时的贡献为 \(j\times f(i-1,j+1)\)。
https://www.luogu.com.cn/record/48188085
P2387 [NOI2014] 魔法森林
考虑把边按照 \(a_i\) 排序,然后对于每新加一条边,我们对图做以 \(b_i\) 为边长的瓶颈最短路。但如果更加玄学一点,使用 SPFA 就会有意想不到的收获。由于 SPFA 每次都是对图从一些点出发进行一次松弛,所以实际上每加入一条边,我们只需要从这条边所连接的两个点开始松弛即可。(听说叫动点SPFA?)
在水的数据下轻松吊打 LCT(指排到最优解第七)
https://www.luogu.com.cn/record/48191605
CF1495D BFS Trees
考虑对于 \((x,y)\) 的 BFS tree,必须满足 \((x,y)\) 的最短路只有一条,且每个点要满足其两个条件之一
- \(u\) 在 \((x,y)\) 最短路上(\(d_{x,u}+d_{u,y}=d_{x,y}\))
- \(u\) 能选出一个父亲节点 \(v\) 使得 \(v\) 在 \((u,x)\),\((u,y)\) 最短路上,即 \(d_{x,v}+1=d_{x,u}\) 且 \(d_{y,v}+1=d_{y,u}\)。
复杂度 \(O(n^2m)\)。
https://codeforces.com/problemset/submission/1495/110726349
CF Round #709 Div1
https://codeforces.com/contest/1483
小号做出1A,1C然后上分
CF1497C k-LCM
首先看 Easy version,我们得到结论:
\(n\equiv 0 \pmod 4\) 时,答案为 \(\frac{n}{2},\frac{n}{4},\frac{n}{4}\)。
\(n\equiv 2 \pmod 4\) 时,答案为 \(2,\frac{n-2}{2},\frac{n-2}{2}\)。
\(n\equiv 1,3\pmod 4\) 时,答案为 \(1,\frac{n-1}{2},\frac{n-1}{2}\)。
对于 Hard Version,其实还是一样的,我们前 \(k-3\) 全部塞 1 即可。
https://codeforces.com/contest/1497/submission/110732897
CF1494E A-Z Graph
一个好 trick
存在长 \(k\) 的回文路径相当于
- \(k\) 为奇数时存在一条双向边
- \(k\) 为偶数时存在一条 \(u\to v\) 和 \(v\to u\) 使得边权相同
用一个 map 去维护即可。
https://codeforces.com/contest/1494/submission/110816524
3.24 CX 测验
A [USACO06JAN]Redundant Paths
问在图上要添加多少条边,使得其成为一个边双。
考虑对图进行边双缩点。我们发现设度数为 \(1\) 的节点为 \(d\) 个, \(ans=\lceil\frac{d}{2}\rceil\)。
B BZOJ3331 压力
考虑建出圆方树,然后一个一个路径相当于给圆方树上的所有圆点的值 \(+1\),然后最后问每一个圆点的值。显然方点加不加都没事儿,所以我们可以直接树上差分结束。
P5776 [SNOI2013]Quare
求边权最小的点集为原图点集的边双。考虑状压。一个边双可以拆成一个边双加一条链,代价最小即为链两端的点连线加入这个边双。\(f_{S}\) 表示点集为 \(S\) 的边权最小的边双。
考虑设几个辅助数组。\(c_{S,u,v}\) 表示 \(S\) 中以 \(u,v\) 为端点的链的最小权值和,\(g_{S,u,0/1}\) 表示将 \(u\) 连到 \(S\) 中去的最小/次小代价。\(g\) 可以暴力枚举,\(c\) 有 \(c_{S,u,v}=\min_{k\neq i} h_{S-u,k,v}+w_{u,k}\)。
初始值有
https://www.luogu.com.cn/record/48417687
CF1494D Dogeforces
首先可以得到根节点权值 \(\max lca_{u,v}\)。
假设我们得到了一个节点作为子树根节点 \(u\) 和其所有子树内叶节点,那么对于两个叶节点 \(s_i,s_j\),如果他们的 \(lca\neq u\),则这两个点处在一个子树中。
由于最多分成 \(O(n)\) 个子树,然后每一个节点要 \(O(n^2)\) 枚举叶节点,所以总复杂度 \(O(n^3)\)。
https://codeforces.com/contest/1494/submission/110974588
CF356A Knight Tournament
一开始想到一个线段树解法,但实际上直接并查集一样地维护一个 next 指针显然更好。显然每一个 knight 只会被删除一次,于是总复杂度是 \(O(n)\) 的。
http://codeforces.com/contest/356/submission/111219676
P3457 [POI2007]POW-The Flood
肯定是把抽水机贪心地放到比较高度比较小的地方,所以我们高度从低到高考虑。如果高度都不同,我们就在那个地方放入一个抽水机,然后给高度不比自己大的地方连边,形成连通块。显然一个连通块只需要一个抽水机。对于高度相同的点,我们把所有同一高度的点连边完毕后再加入抽水机,否则会出问题。
https://www.luogu.com.cn/record/48554001
P3465 [POI2008]CLO-Toll
显然我们需要对于每一个连通块构造出一个外向奇环树形图(即每个点的入度为 \(1\))。那么首先我们先弄出连通块。如果这个连通块的边数 \(<\) 自身点数,那么必然无解。然后 dfs 找一个环。这个环上的点就构成一个有向图中的环,然后环上点连向其他点。
https://www.luogu.com.cn/record/48568526
P7428 [THUPC2017]母亲节的礼物
首先一定有解。
考虑用调整法去做。首先给每个点随一个值,然后把所有不符合要求的点全部 push 进一个队列。对于队列中的点,如果它不符合要求(即 \(cnt_{u,c_i}>1\)),那么就把它改成那个 \(cnt_{u,c_i}\) 最小的点,然后更新邻居。显然 \(\min cnt_{u,c_i}\le 1\)(鸽巢原理),每个点最多会被每隔邻居更新一次,所以调整次数最多为 \(8n\),所以总复杂度 \(O(TN)\)。
https://www.luogu.com.cn/record/48652027
P6822 [PA2012]Tax
考虑最朴素的方法。对于两条边 \((a,b),(b,c)\),我们考虑在新图上建边 \((a,c)\),权值为两条边的最大值。这样边数是 \(O(n^2)\) 的。
然后考虑把点的边转化为边的边。一条边在新图上对应一个点。对于相邻的边 \(e_1,e_2\) 对应的点 \(u_1,u_2\) 权值为 \(\max(w_{e_1},w_{e_{2}})\)。
考虑前缀优化建图。
https://www.luogu.com.cn/record/48673814
3.31 CX 测验
A 游戏机器人
裸分层图最短路,代码细节比较复杂
B 战争
裸平面图最小割->对偶图最短路,但是Implementation(主要在建图)异常复杂(所以没写)
C Cow Relays
floyd广义矩阵快速幂裸题
CF128B String
感觉后缀树有些生疏了啊…… 主要还是要有更加仔细更加合理的推导。树上统计(尤其是边能代表很多串的后缀树)最怕变量设的乱。
https://codeforces.com/contest/128/submission/111638340
CF1120C Compress String
考虑 DP
然后我们考虑用刷表法更新
对于第二个考虑增量式去统计(因为是单调的)。至于查询是否是子串,增量地在后缀树上跑即可,维护到哪个节点的第几个字符。
https://codeforces.com/contest/1120/submission/111642856
CF757F Team Rocket Rises Again
这种最短路问题考虑建出最短路DAG。然后就是DAG上支配树问题了。
顺便复习一下这两个东西。单源无汇最短路DAG的边在DAG内当且仅当 \(d_u+w_{u,v}=d_v\)。关于DAG支配树,一个点在支配树上的父亲节点为所有连向它的点的支配树上 LCA。
https://codeforces.com/contest/757/submission/112013170
有向图支配树
见另一个blog
CF1338D Nested Rubber Bands
考虑选择一条链,然后让它奇数深度的点构成同心圆。然后我们存在一些点使得其跨过一些圆。观察后发现,我们发现其实就是树上最大毛毛虫独立集。DP 即可。\(f_{u,0/1}\) 表示 \(u\) 子树 \(u\) 是否选择的情况。
http://codeforces.com/contest/1338/submission/112292932
CF773D Perishable Roads
比较长,扔自己的题解了。https://www.luogu.com.cn/blog/forever-captain/solution-cf773d
CF542E Playing on Graph
模拟一下,我们发现有奇环,那么必然无解(一定可以规约到 \(n=m=3\))的场面。
否则这个图就是二分图。考虑拎起一个节点建出 BFS 树。由于是 BFS 树,所以其非树边都连接着深度相差不超过 1 的点;由于是二分图,所以起非树边连接的必然不是同深度节点。对于这样,我们就可以把一个 BFS 树同一深度的一层给搞成 1 个点。显然我们可以通过题目中的步骤完成。于是相当于就是 BFS 树的最大深度,即一个点为源点的最短路的最大值。
http://codeforces.com/contest/542/submission/112342279
P4351 [CERC2015]Frightful Formula
比较长,扔自己的题解了。https://www.luogu.com.cn/blog/forever-captain/solution-p4351