2026.7.24 模拟赛

T1

给定一个 \(1 \sim n\) 的排列 \(a\)。有 \(q\) 次询问,每次询问给定 \([l,r]\),你可以指定若干个 \([l,r]\) 的子区间,随后你可以以任意顺序对这些区间内的元素循环移位,你的目标是用最少的指定子区间数排列区间内的元素,使得对于 \(l \le i \le r\) 均有 \(a_i=i\)。输出这个最小个数,或报告无解。
\(1 \le n,q \le 5 \times 10^5\)

发现可以指定 \([l,r]\)\([r-1,r]\) 来实现交换任意两个数,因此答案 \(\le 2\)

答案为 \(-1\) 当且仅当区间存在一个数不在 \([l,r]\) 内。答案为 \(0\) 当且仅当所有 \(l \le i \le r,a_i=i\)。答案为 \(1\) 时需要先缩掉左右极长 \(a_i=i\) 前后缀,然后判断剩余区间是否能通过循环移位拼出。这些判断都不难通过维护区间 \(a_i\)\(i-a_i\)\(\max,\min\) 来实现。

时间复杂度 \(O((n+q) \log n)\)

T2

发现我们在图上走的时候,钱数显然是不增的,因此我们的活动范围是减小的。

这样非常难受,因此我们不妨倒着看,这样我们的活动范围是变大的。现在问题变成,初始在某一个节点,进入一个节点获得 \(b_i\) 的钱,出一个节点时需要至少有 \(a_i\) 的钱,最小化最后的钱数。

那么相当于至少需要 \(c_i=\max(0,a_i-b_i)\) 才能进入一个节点,对着这个建立 Kruskal 重构树,那么到达一个点就能到达其子树。令 \(f_u\) 代表到达 \(u\) 的最小钱数,有 \(f_u=\min\limits_{v \in \text{son}(u)}(\max(f_v,c_u-s_v))\),其中 \(s_u\)\(u\) 子树中所有叶子的 \(b_i\) 和。

答案为 \(f_{rt}+s_{rt}\),时间复杂度 \(O((n+m) \log (n+m))\)

T3

待补。

posted @ 2026-07-24 16:52  luqyou  阅读(15)  评论(0)    收藏  举报