#CF1945E. 二分查找

二分查找

二分查找

时间限制:2s
空间限制:256MB

题目描述

Anton 在徒步旅行时感到无聊,想要解一道题。他问 Kirill 有没有新题,Kirill 当然有。

你得到了一个长度为 nn 的排列 pp,以及一个需要查找的数字 xx。长度为 nn 的排列是一个包含 11 到 nn 的 nn 个互不相同整数的数组,顺序任意。例如,[2,3,1,5,4][2,3,1,5,4] 是一个排列,但 [1,2,2][1,2,2] 不是排列(22 在数组中出现了两次),[1,3,4][1,3,4] 也不是排列(n=3n=3 但数组中有 44)。

你自认为是个很酷的程序员,所以你打算用高级算法——二分查找来查找 xx。但你忘了二分查找需要数组有序。

你没有放弃,决定无论如何都要用这个算法。为了得到正确答案,你可以在运行算法前,最多进行 22 次操作:每次选择下标 ii、jj(1≤i,j≤n1\le i,j\le n),交换第 ii 个和第 jj 个位置上的元素。

之后,执行如下的二分查找算法。算法开始时,声明两个变量 l=1l=1,r=n+1r=n+1。然后执行如下循环:

  1. 如果 r−l=1r-l=1,结束循环。
  2. m=⌊r+l2⌋m = \lfloor \frac{r+l}{2} \rfloor。
  3. 如果 pm≤xp_m \le x,则令 l=ml=m,否则令 r=mr=m。

你的目标是在算法开始前重新排列数组,使得算法结束后 pl=xp_l = x。可以证明,最多 22 次操作总是足够的。

输入格式

每个测试点包含多组测试数据。第一行包含一个整数 tt,表示测试数据组数。接下来是每组测试数据的描述。

每组测试数据的第一行包含两个整数 nn 和 xx,分别表示排列的长度和要查找的数字。

第二行包含排列 pp,用空格隔开(1≤pi≤n1 \le p_i \le n)。

输出格式

对于每组测试数据,第一行输出一个整数 kk(0≤k≤20 \le k \le 2),表示你进行了多少次操作。接下来的 kk 行,每行输出两个整数 ii、jj(1≤i,j≤n1 \le i,j \le n),表示你交换了第 ii 个和第 jj 个位置上的元素。

注意,你不需要最小化操作次数。

样例输入 1

5
6 3
1 2 3 4 5 6
6 5
3 1 6 5 2 4
5 1
3 5 4 2 1
6 3
4 3 1 5 2 6
3 2
3 2 1

样例输出 1

0
1
3 4
2
2 4
1 5
2
4 5
2 4
1
1 3

数据范围

  • 对于所有数据,满足 1≤t≤2×1041\le t\le2\times10^4。
  • 对于所有数据,满足 1≤x≤n≤2×1051\le x\le n\le2\times10^5。
  • 对于所有数据,满足 1≤pi≤n1\le p_i\le n。
  • 对于所有数据,满足 pi 两两不同p_i\text{ 两两不同}。
  • 所有测试组共同满足 ∑n≤2×105\sum n\le2\times10^5。
子任务编号 分值 特殊限制
1 20 n≤8n\le8,且一个输入文件内的 ∑n≤40\sum n\le40
2 n≤500n\le500,且一个输入文件内的 ∑n≤1000\sum n\le1000
3 30 x∈{1,n}x\in\{1,n\}
4 无特殊限制