做题(部分)笔记(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

\[|a_x-a_y=1| \to a_x\ge a_y-1, a_y\ge a_x-1, a_y\neq a_x \]

用差分约束即可。

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_j(u,i)=\min (f_{j-1}(u,i)+g(v,i),f(v,i+1)+g_{j-1}(u,i+1))\\ g_j(u,i)=\sum g_{v,i-1}\\ g_j(u,0)=f_j(u,0)\\ f_0(u,i)=w_u \]

然后还要更新一下 \(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\) 那么就直接不要计算了;然后就可以过去了(

https://loj.ac/s/1093977

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. 连通块是一棵树

在每个度为 1 的节点处装上即可

  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\) 个连续段。对于转移,要么它连接两个连续段;要么它新开一个连续段。不能只接在一个连通块上,这样会导致后面更大的数插入到这里后出现问题。

  1. 新开连续段。此时的贡献为 \(j\times f(i-1,j-1)\)。注意要特判当 \(i > s\) 或者 \(j < s\) 那么前面的系数不是 \(j\) 而要减去 \(1\) 或者 \(2\)

  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}\)

\[f_{S}=\min_{T\subset S} \begin{cases} f_{S-T}+c_{T,u,v}+g_{S-T,u,0}+g_{S-T,v,0} &|T|>1\\ f_{S-T}+g_{S-T,u,0}+g_{S-T,u,1} &|T|=1 \end{cases} \]

初始值有

\[f_{\{u\}}=f_{\varnothing}=0\\ c_{\{u\},u,u}=0\\ \]

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

\[f_i=\min \begin {cases} f_{i-1}+a\\ f_{j}+b & (S[j+1,i]\subseteq S[1,j]) \end {cases} \]

然后我们考虑用刷表法更新

\[\begin{cases} f_i+a\to f_{i+1}\\ f_i+b\to f_{j} &(S[i+1:j]\subseteq S[1:i]) \end{cases} \]

对于第二个考虑增量式去统计(因为是单调的)。至于查询是否是子串,增量地在后缀树上跑即可,维护到哪个节点的第几个字符。

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

posted @ 2021-03-15 00:07  LarsWerner  阅读(111)  评论(0)    收藏  举报