CF1945E 解题报告
Sternenlicht · · 题解
思路:分类讨论。
先要想到一个性质:若
-
二分结束后
p_l = x 。此时显然不用交换,已经满足题意。输出
0即可。 -
二分结束后
p_l \neq x 。-
若是,那么当 $x = p_m$ 的时候,$l$ 是要赋为 $m$ 的,此时 $p_l = x$。那为什么最后 $p_l < x$ 呢?显然,在此次判断之后,$l$ 还被更新过至少 $1$ 次。我们考虑将二分结束后的 $p_l$ 与 $x$ 交换后,会发生什么。由于 $p_l$ 和 $x$ 均满足 $\le x$ 这个条件,即都是使 $l$ 更新,所以二分时进行的操作是一样的!也就是说,把这两个数交换后,并不会影响原二分的运行过程。那么交换 $x$ 和 $p_l$ 即可,操作次数为 $1$。 若否,那么由性质可知,交换 $x$ 和 $p_l$ 即可,操作次数为 $1$。 -
-
现在观察分类讨论的第
注意输出的是交换数字的位置,在读入时记录
#include <bits/stdc++.h>
#define il inline
namespace Fast_IO {
template <typename T> il void read(T &x) {
x = 0; int f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) x = x * 10 + (ch - 48), ch = getchar();
x = f ? -x : x;
}
template <typename T, typename ...Args>
il void read(T &x, Args& ...args) {read(x), read(args...);}
template <typename T> il void write(T x, char c = '\n') {
if (x) {
if (x < 0)x = -x, putchar('-');
char a[30]; short l;
for (l = 0; x; x /= 10) a[l ++] = x % 10 ^ 48;
for (l --; l >= 0; l --) putchar(a[l]);
} else putchar('0');
putchar(c);
}
} using namespace Fast_IO;
using namespace std;
const int Maxn = 200005;
int a[Maxn];
signed main() {
int T; read(T);
while (T --) {
int n, x, ans; read(n, x);
for (int i = 1; i <= n; i ++) {
read(a[i]);
if (a[i] == x) ans = i;
}
int l = 1, r = n + 1;
while (r - l > 1) {
int mid = (l + r) >> 1;
if (a[mid] <= x) l = mid;
else r = mid;
}
if (a[l] == x) puts("0");
else puts("1"), write(l, ' '), write(ans);
}
return 0;
}