CF1945E Binary Search

题目描述

Anton 在徒步旅行时感到无聊,想要解一道题。他问 Kirill 有没有新题,Kirill 当然有。 你得到了一个长度为 $n$ 的排列 $p$,以及一个需要查找的数字 $x$。长度为 $n$ 的排列是一个包含 $1$ 到 $n$ 的 $n$ 个互不相同整数的数组,顺序任意。例如,$[2,3,1,5,4]$ 是一个排列,但 $[1,2,2]$ 不是排列($2$ 在数组中出现了两次),$[1,3,4]$ 也不是排列($n=3$ 但数组中有 $4$)。 你自认为是个很酷的程序员,所以你打算用高级算法——二分查找来查找 $x$。但你忘了二分查找需要数组有序。 你没有放弃,决定无论如何都要用这个算法。为了得到正确答案,你可以在运行算法前,最多进行 $2$ 次操作:每次选择下标 $i$、$j$($1\le i,j\le n$),交换第 $i$ 个和第 $j$ 个位置上的元素。 之后,执行如下的二分查找算法。算法开始时,声明两个变量 $l=1$,$r=n+1$。然后执行如下循环: 1. 如果 $r-l=1$,结束循环。 2. $m = \lfloor \frac{r+l}{2} \rfloor$。 3. 如果 $p_m \le x$,则令 $l=m$,否则令 $r=m$。 你的目标是在算法开始前重新排列数组,使得算法结束后 $p_l = x$。可以证明,最多 $2$ 次操作总是足够的。

输入格式

每个测试点包含多组测试数据。第一行包含一个整数 $t$($1 \le t \le 2\cdot 10^4$),表示测试数据组数。接下来是每组测试数据的描述。 每组测试数据的第一行包含两个整数 $n$ 和 $x$($1 \le x \le n \le 2\cdot 10^5$),分别表示排列的长度和要查找的数字。 第二行包含排列 $p$,用空格隔开($1 \le p_i \le n$)。 保证所有测试数据中 $n$ 的总和不超过 $2\cdot 10^5$。

输出格式

对于每组测试数据,第一行输出一个整数 $k$($0 \le k \le 2$),表示你进行了多少次操作。接下来的 $k$ 行,每行输出两个整数 $i$、$j$($1 \le i,j \le n$),表示你交换了第 $i$ 个和第 $j$ 个位置上的元素。 注意,你不需要最小化操作次数。

说明/提示

由 ChatGPT 4.1 翻译