【题解】Solution Set - NOIP2024集训Day55 图论杂题3
【题解】Solution Set - NOIP2024集训Day55 图论杂题3
https://www.becoder.com.cn/contest/5636
「ABC187E」Through Path
注意:无根树是无向边。
一个相当于子树加 \(k\),一个相当于除子树加 \(k\)。
3min
「HNOI 2018 省队集训 Day 5」party
一个结论是:题中的 party 一定是在这 \(c\) 个点的 lca 处。
注意到 \(m\) 比较小,考虑暴力一点的做法:bitset !
(FAKE
我们先树剖 + bitset 拿到每个人可以拿到哪些特产。然后把每个人只有她可以拿的特产找出来,具体的这个就是其她几个人的 bitset 与起来,跟这个人异或,然后再跟自己与起来。
然后呢?
把所有人能拿到的特产的并集拿到,然后按可以被拿的人数从小到大依次贪心?好像也不对。
二分图?但是怎么判每个人拿的特产数相等?
23min
https://www.cnblogs.com/lcyfrog/p/13024371.html
因为 \(c\) 最多只有 \(5\),考虑 Hall 定理最原始的形态,也即去枚举 \(S\) 的子集。
我们设每个人在答案中带来的特产数为 \(x\),对于枚举的一个子集 \(S^\prime\),我们考虑 \(S^\prime\) 在中的每一个点拆成 \(x\) 个,这样就保证了每个人拿的特产数相等。根据 Hall 定理,此时我们存在完美匹配的充要条件是 \(|S^\prime|\times x\le|N(S^\prime)|\),所以此时最大的 \(x=\left\lfloor\dfrac {|N(S^\prime)|}{|S^\prime|}\right\rfloor\)。也就是对于每个子集求出的最大的 \(x\) 再一起取 \(\min\) 就是答案了。
关于实现:
-
知道每个人可以拿到哪些特产有两个途径:(每次查询的时间复杂度为
-
主席树 + 树上差分:\(O(cm)\);(查询整棵线段树是 \(O(m)\) 不是 \(O(m\log m)\) 啊。
-
树剖 + bitset:\(O(c\log n\frac m\omega)\)。
一种对于树剖的常用两只 \(\log\) 化单 \(\log\) 的技巧。
维护每个点到其重链顶间的数据,这样跳重链的时候可以 \(O(1)\) 查询。
只用最后 \(u,v\) 在同一重链上的时候,需要数据结构的一个 \(\log\)。
所以,我们就把树剖和数据结构,在算时间复杂度时的乘法变成了加法。
实际上在做的时候,不如用 \(\frac 1\omega\) 去换 \(\log n\)。实现难度上其实差不多。
-
-
算邻域的时候,可以状压 dp 算,而不用每次都取枚举当前子集的每个元素的邻域再并起来。
「ZJOI2018」胖
一般图是不好优化这个过程的。考察题目给的:链 + 中心点 的结构。
我们对于每个 \(a_i\) 分开计算贡献,显然她能松弛(产生贡献)的点是一个区间。
这个区间肯定是有单调性的,考虑去二分这个区间,看她最先不能越过哪个 \(a_i\)。
另外一个点 \(a_i\) 能够堵住她,当且仅当:到这的经过边数不多于她,且到这的距离更短。
(自己想整个过程的状态去了,绕了很多弯,其实只用着眼于二分的这个点。
我们需要 \(O(1)\) check。
…… 20min
借鉴……
哦!稍微推个式子,wssb,差一点啊。
设 \(dis_i\) 表示 \(i\) 到 \(1\) 的距离。
设当前枚举的 \(a_i\) 为 \(A\),二分的点为 \(x\)。经过边数不多于她,就要求我们在 \([x-(A-x),x+(A-x)]\) 内找到到 \(x\) 的最短距离。
也就是 \(l_i+|dis_{a_i}-dis_x|\),拆绝对值:
- 如果 \(a_i\) 在 \(x\) 左侧,\(dis=l_i+(dis_x-dis_{a_i})\)。
- 如果 \(a_i\) 在 \(x\) 右侧,\(dis=l_i+(dis_{a_i}-dis_x)\)。
所以我们只需要用 st 表去维护 \(l_i\pm dis_{a_i}\) 的最小值,然后再取 \(\min\) 就行了。
注意一下去重的问题。
如果一个点对两个 \(a_i\) 都可以有贡献,我们钦定对编号更小的 \(a_i\) chan