CodeForces-2138B Antiamuny Wants to Learn Swap

CodeForces-2138B Antiamuny Wants to Learn Swap

tag: *1900;逆序对,单调栈,双指针

对于长度为 \(m\) 的数组 \(b\),你可以进行以下两种操作:

  1. 选择一个下标 \(1\le i\le m-1\),然后交换 \(b_i\)\(b_{i+1}\) 的值。
  2. 选择一个下标 \(1\le i\le m-2\),然后交换 \(b_i\)\(b_{i+2}\) 的值。

定义:

  • \(f(b)\) 表示使用任意多次操作 1 和 一次 操作 2 将数组 \(b\) 重排为非递减序列所需的最小操作次数;
  • \(g(b)\) 表示 只使用操作 1 将数组 \(b\) 重排为非递减序列所需的最小操作次数。

如果 \(f(b) = g(b)\),那么这个数组 \(b\) 被称为 完美 的。

给定一个长度为 \(n\)排列 \(a\)。回答 \(q\) 次询问,每次询问给定 \(l,r\),判断连续子数组 \(a[l..r]\) 是否为完美的。

\(1\le t\le 5\times10^4\)\(1\le n, q,\sum n,\sum q\le 5\times 10^5\)

通过操作 1 总可以对 \(a\) 进行排序,操作数即为 逆序数

考虑操作 2 的影响是什么。假设现在要将 \(3,2,1\) 排序,本来需要先进行两次操作 1 变为 \(1,3,2\),再进行一次操作 1 变为 \(1,2,3\),但有了操作 2,就可以进行一次操作 2,直接变为 \(1,2,3\)(一次减少 \(\ge2\) 个逆序对)。

扩展一下,在用操作 1 不断将后面的元素往前面交换的过程中,我们可以构造一个局面出现 \(a_{i}>a_{i+1}>a_{i+2}\),从而像上面一样,减少操作数。

而可以用操作 1 构造出这样的局面,当且仅当存在 \(i<j<k\) 满足 \(a_i>a_j>a_k\)。这也是 \(f(a)\ne g(a)\) 的充分条件。

那如果不存在 \(a_i>a_j>a_k\),是否一定满足 \(f(a)=g(a)\) 呢?答案是肯定的,因为在这种情况下,用操作 2 至多能减少一个逆序对,和操作 1 的作用相同。

现在问题就变为,给定 \(l,r\),判断是否存在 \(l\le i<j<k\le r\) 满足 \(a_i>a_j>a_k\)

\(L(j)\) 为满足 \(i<j\)\(a_i>a_j\) 的最大的 \(i\)\(R(j)\) 为满足 \(k>j\)\(a_k<a_j\) 的最小的 \(k\),显然 \(L(j)<R(j)\)

那么 \(l,r\) 满足条件当且仅当存在 \(l\le j\le r\) 满足 \(l\le L(j),R(j)\le r\)。序列 \(L,R\) 可以用 单调栈 求出。

因此,问题转化为,给定 \(n\) 个区间 \([L(j),R(j)]\),每次判断是否存在 \([L(j),R(j)]\subset[l,r]\),若存在则 \([l,r]\) 是不完美的。

预处理 \(f(l)=\min\limits_{L(j)\ge l}\{R(j)\}\),则 \([l,r]\) 是不完美的当且仅当 \(r\ge f(l)\)

\(O(n\log n)\):将区间 \([L(j),R(j)]\) 按左端点从小到大为第一关键字、右端点从小到大为第二关键字排序,然后双指针处理。

\(O(n)\)(官方题解):没看懂。

Submission #346927072 - Codeforces

posted @ 2025-11-01 16:29  f2021ljh  阅读(6)  评论(0)    收藏  举报