省选模拟4
A
小丑做法,设 \(f_{S,i,j}\) 为使用边权 \(\le j\) 的边连通了集合 \(S\),里面使用了 \(i\) 个 \(a\) 的最小生成树。
转移朴素枚举,复杂度 \(O(3^nm^3)\)
B
是原题。
注意到一个点走过一轮后,从父亲离开后下一次访问会完全访问。
因此可以 dfs 求得一个节点会在第几轮整体遍历的时候走到(也就是从根节点离开再回到根节点的过程,本质上是数有多少个祖先跳过了这个方向的子树)
显然最多 \(n\) 轮后就会开始循环,且将最后的完整的访问序列拿出来后,任意轮的访问序列都是其一个子序列(选择部分跳过,也就是跳过轮数不够的部分)。
那么对于一个询问,可以先二分得到其轮数,然后在当前轮的状态下查找第某个访问的节点
使用线段树,利用双指针去掉二分。
C
考虑真正的最短路应该如何走。
不妨将这个排列视作棋盘上的 \(n\) 个棋子,不重行不重列。
那么有:
这样可以看出,一个连通块必然是原排列的一段区间,且若 \([i,i+1]\) 是分界点,那么满足 \(\max_{j\le i}p_j=i\)
那么我们现在就当连通处理。
考虑这时候右上部分和左下部分的问题事实上是独立的。
例如右上部分,我们一定会走一个一步到达的最上方点或者最右边点。
我们不妨以右上部分为例,拿出这两个点,
这时候等效于走到这个红点。
那么我们可以通过一定的预处理,直接求得对于每个 \(i\),这个红点的位置。
同时这时候我们的答案就呼之欲出了:\(\sum_{x=1}^ndis(x,i)=\sum_{j=1}^n\sum_{x=1}^n[dis(x)\ge j]\)。
也就是,事实上答案是这个 “红点” 路径,所有“红点”的右上角矩阵中点个数之和。
这样就可以通过一定的预处理得到一个平方复杂度的做法。
现在考虑优化它。
事实上,我们将整个跳跃过程的图建立出来,我们声称其点个数数量级不超过 \(n\sqrt n\)。
证明考虑,除了起始点之外,走到的任意一个点 \((x,y)\),贡献这两个坐标的点是向左倾斜的,也就是设点 \(i,j\) 贡献了点 \((x,y)\),那么 \(i<j\leftrightarrow p_i>p_j\)。
因此拿出所有的这样的 \((i,j)\) 并拿出这样的点,对于某个固定的 \(x\),拿出所有“红点”并按照 \(y\) 从大到小排序,设为 \(b_1\sim b_m\)。
考虑将其中前 \(B\) 个标记为好点,那么考虑从 \((x,x)\) 开始跳的过程,若经过了坏点 \((x,y)\),那么下一步 \(y\) 会直接变成 \(b_m\) ,至少不小于,那么这直接最少减小了 \(B\),因此每条路径最多经过 \(\frac{n}{B}\) 个坏点,而好点总共只有 \(nB\) 个,因此总点数不超过 \(\frac{n^2}{B}+nB\),对于任意正整数 \(B\) 成立,取 \(B=\sqrt n\) 知点数不超过 \(O(n\sqrt n)\) 量级,而每个点出度都是 \(1\)。
然后考虑答案的计算,直接建立出这棵树,然后从上往下扫描线即可。
注意只需要加入 \(O(n)\) 个点,却有着 \(O(n\sqrt n)\) 次查询,利用分块计数,维护块内前缀和和整块前缀和即可。