NOIP2024集训 Day51 略解
前言
你只记得,努力之后,是九死一生。却忘了,若不努力,便是十死无生。
感觉今天的题充其量也是一堆典题,可是我还是菜的不会几道,做过的都不会了。。
Cheap Robot
显然,你可以先从每个充电站出发跑一个多源最短路,得到每个点 \(x\) 到其最近的充电站的距离 \(dis_x\)。
有一个更加显然的东西是,你无论当前走到了哪个点,假设是 \(x\),当前剩余容量为 \(y\),你一定要满足 \(dis_x\le y\)。
同理,如果你要到达一个点,那么油箱容量也必须 \(\ge dis_x\)。
那么,你发现,对于任意一条边 \((u,v,w)\),经过他所需的最小容量就是 \(dis_u+dis_v+w\),你要求的就是对于 \(a\to b\) 的每条路径上经过每条边的最小容量最大值的最小值。
显然直接上 \(\texttt{Kruskal}\) 重构树就直接秒了。
有序奶牛
题目保证按照输入的偏序建边一定是个 \(\texttt{Dag}\),而我最开始根本就没有发现这件事情。
一个比较直观的删边方法就是你再删掉这条边之后,剩下的边仍然可以使得这条边的起点到达终点。
具体实现就是你先跑一边拓扑序,然后对于每一条边 \(u,v\) 按照 \(\text{topo}_u\) 为第一关键字,\(\text{topo}_v\) 为第二关键字从小到大排序。
然后你按照排序后的顺序遍历每条边,更新连通性即可,可以通过 \(\texttt{Bitset}\) 做到 \(\mathcal{O}(\frac{nm}{w})\)。
变换序列
按照题目中给得 \(D(i,j)\) 的定义和具体的值,每个点最多连出去四条边,然后直接跑最小字典序完美匹配即可。
字典序的话你直接对于边权最小到大遍历即可。
Dynamic Shortest Path / 动态最短路
挺不错的一道题。
暴力思路是你对于每次操作之后跑一遍 \(\texttt{Dijkstra}\),复杂度 \(\mathcal{O}(q\times m\log n)\),直接炸掉。
我们发现这个 \(\log n\) 非常难受,想一下有没有办法把他搞掉。
有一个比较重要的东西是,如果 \(\forall x\in[1,n],0\le dis_x\le V\),那么你可以把堆优化 \(\texttt{Dijkstra}\) 改成用桶排优化,复杂度可以做到 \(\mathcal{O}(V+n+m)\)。
我们发现每次修改 \(c\) 条边,每次边权加一,而 \(\sum c\le 10^6\),故我们先考虑跑一遍 \(\texttt{Dijkstra}\) 求出初始 \(dis_x\),然后每次修改之后求得每个点距离的增量数组 \(add_x\)。
观察到 \(add_x=\min_{(x,j,w)\in E} dis_j+add_j+w-dis_x\),且满足对于每次修改,有 \(\forall x,x\in[1,n],0\le add_x\le c\),故总复杂度 \(\mathcal{O}(q\times (c+n+m))\) 可过。
Exhausted?
显然有一个非常劣的贪心性质是,按照 \(l_i\) 为第一关键字,\(r_i\) 为第二关键字按照顺序填,填不下就往后面补。
但是由于无法满足 \(r_i\) 单调,故直接这样写是错的。
我们再考虑一下,如果左边塞不下了,那么无论如何,都要有一个人坐到右边,那么我们可以吧左边有位置的一个人踢出来,让他坐在右边。那我们肯定是把 \(r_i\) 小的踢出来,这样显然更优。
那就好办了,我们往左边塞的时候,坐不下就把 \(r_i\) 最小的踢掉,可以用小根堆维护。把左边塞完之后,再把没座位的,以同样的方法往右边塞,实在没办法就只能补了。
对于贪心的正确性,可以从霍尔定理的角度进行理解。
自行车
首先,我们先看什么时候一定不合法。即你对于任意三个点 \(i,j,k\) 如果其满足 \(b_{i,j}<\min(b_{i,k},b_{k,j})\) 那就显然不合法。(根据合法的定义,这个很直观)
然后这个时候你直接搞一个完全图应该就可以直接合法了,但是边数会炸掉。考虑能不能搞出一颗合法的生成树。
显然这个地方你要搞一颗最大生成树,因为你是要两个点路径上最小值的最大值为 \(b_{i,j}/c_{i,j}\)。此时我们先只考虑 \(b\)。暴力 \(n^2\) 建边,然后跑生成树。观察到如果此时连接的两个点 \((i,j)\) 是联通的,那么你显然不需要连,因为此时你显然满足对于同样在这个连通块内的点 \(k\),有 \(b_{i,j}\le \min(b_{i,k},b_{k,j})\),而为了合法,你又必须满足 \(b_{i,j}\ge \min(b_{i,k},b_{k,j})\) 于是你有 \(b_{i,j}=\min(b_{i,k},b_{k,j})\),此时你这颗生成树构建出来对 \(b\) 显然是合法的。
同理,直接对 \(c\) 再跑一遍。但是对于 \(b_{i,j}+c_{i,j}< w\) 这些边你是绝对不可以加进去的,最开始跑生成树的时候直接跳过即可,因为他显然加进去之后会导致不合法。
然后将 \(b,c\) 的答案合并起来即可。
兔兔与蛋蛋
一道不错的二分图博弈好题。
如果你直接按照局面暴力 \(2^{n\times m}\) 建边你就废了。
首先有一个很重要的性质是,每个黑白棋只会被移动一次,这个应该可以非常简单的通过奇偶性进行证明。
而有了这个性质的基础,我们就可以尝试把每个点放在二分图上,对于空格看作黑点,因为是兔兔先移动,黑白染色直接放上去,然后黑白之间建边。
由于每个点只会被移动一次,换句话说就是棋盘上每个点只会被经过一次,从而对应了二分图博弈类似的下棋问题,也迁移到了二分图匹配每个点只能在一个匹配上面,然后就直接套板子。
对于兔兔的失误在哪里,就是他操作之前是必胜,操作之后是必败,这一步就是失误,直接暴力二分图博弈判断即可。\
后记
I wish I was special
You're so very special
But I'm a creep, I'm a weirdo