CF2147F Exchange Queries

题目大意:

有两个排列,\(i\) 能换成 \(j\) 当且仅当这两个排列中至少有一个排列,\(i\) 排在 \(j\) 前面。
\(q\) 次交换排列的两个数,每次交换后求有多少 \(i,j\) 满足 \(i\) 能通过若干次交换变成 \(j\)
\(n,q \le 10^5\)

解题思路:

考虑将第一个排列重新标号成 \(1 \sim n\)
那么 \(i\) 能交换到 \(j\) 当且仅当 \(i < j\)\(pos_{i} < pos_{j}\)
由于 \(i < j\) 时都能换,所以一个点能交换的一定是个后缀,且这些后缀长度不增。

那么久有可能出现层层嵌套的关系,就比如当前为 \(x\),跳后面 \(pos\) 最小值,跳前面,跳后缀最小值...
这样是不好维护的,因为改变一个位置可能会影响很多的位置的决策。

由于正着的决策过于复杂,所以我们拿所有的减去不可能的。
考虑每个数不可能的一定是个前缀,设前缀为 \(len\),这样就相当于求有多少个 \(x\) 满足 \(x + 1 \sim n\) 跳不到 \(1 \sim x\)

那么就相当于 \(1 \sim x\)\(pos\) 最大值为 \(x\)
考虑对于一个位置 \(x,pos_{x}\),将会让 \(min(x,pos_{x}) \le y < max(x, pos_{x})\) 这些位置不合法。
将第 \(i\) 个位置初始权值设为 \(i\),每次将 \(max(x, pos_{x}) \sim n\) 减一,这样就相当于求所有的所有为 \(0\) 的位置。

而且 \(0\) 如果存在,一定是最小值。

那么我们就存一下最小值和最小值第一/最后一次出现的位置。
O(n \log n)。

这道题感觉有用的是:
当正着做可能会层层嵌套的时候,考虑倒着做。
这个感觉是挺有用的

posted @ 2025-09-26 09:51  positive_deviation  阅读(18)  评论(0)    收藏  举报