给定一个由 n n n 个整数组成的数组 a a a ,找出数值范围 [ x , y ] [x, y] [x,y] ( x ≤ y x \le y x≤y ),并将 a a a 分割成精确的 k k k ( 1 ≤ k ≤ n 1 \le k \le n 1≤k≤n ) 子数组。( 1 ≤ k ≤ n 1 \le k \le n 1≤k≤n ) 子数组,以便:
打印任何能使 y ? x y - x y?x 最小化的解。
输入由多个测试用例组成。第一行包含一个整数 t t t ( 1 ≤ t ≤ 3 ? 1 0 4 1 \leq t \leq 3 \cdot 10^4 1≤t≤3?104 ) - 测试用例的数量。测试用例说明如下。
每个测试用例的第一行包含两个整数 n n n 和 k k k ( 1 ≤ k ≤ n ≤ 2 ? 1 0 5 1 \le k \le n \le 2 \cdot 10^5 1≤k≤n≤2?105 )–数组的长度 a a a 和分区所需的子数组数。
每个测试用例的第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1?,a2?,…,an? ( 1 ≤ a i ≤ n 1 \le a_i \le n 1≤ai?≤n )( 1 ≤ a i ≤ n 1 \le a_i \le n 1≤ai?≤n ) 其中 a i a_i ai? 是数组的 i i i /th 元素。
保证所有测试用例的 n n n 之和不超过 2 ? 1 0 5 2\cdot10^5 2?105 。
每个测试用例打印 k + 1 k+1 k+1 行。
在第一行,打印 x x x 和 y y y - 已发现范围的极限。
然后打印 k k k 行, i i i /-th 应该包含 l i l_i li? 和 r i r_i ri? ( 1 ≤ l i ≤ r i ≤ n 1\leq l_i \leq r_i \leq n 1≤li?≤ri?≤n )-- i i i /th 子数组的极限。
您可以按照任意顺序打印子数组。
在第一次测试中,应该只有一个子数组,它必须等于整个数组。在范围 [ 1 , 2 ] [1, 2] [1,2] 内有 2 2 2 个元素,在 [ 1 , 2 ] [1, 2] [1,2] 外有 0 0 0 个元素,如果选择的范围是 [ 1 , 1 ] [1, 1] [1,1] ,则在 a 1 a_1 a1? 内有 1 1 1 个元素,在 a 2 a_2 a2? 外有 1 1 1 个元素,答案无效。
在第二个测试中,可以选择范围 [ 2 , 2 ] [2, 2] [2,2] ,并将数组分成子数组 ( 1 , 3 ) (1, 3) (1,3) 和 ( 4 , 4 ) (4, 4) (4,4) ,在子数组 ( 1 , 3 ) (1, 3) (1,3) 中,范围内有 2 2 2 个元素( a 2 a_2 a2? 和 a 3 a_3 a3? ),范围外有 1 1 1 个元素( a 1 a_1 a1? ),在子数组 ( 4 , 4 ) (4, 4) (4,4) 中只有 1 1 1 个元素( a 4 a_4 a4? ),且在范围内。
在第三次测试中,可以选择范围 [ 5 , 5 ] [5, 5] [5,5] ,并将数组分成子数组 ( 1 , 4 ) (1, 4) (1,4) 、 ( 5 , 7 ) (5, 7) (5,7) 和 ( 8 , 11 ) (8, 11) (8,11) ,在子数组 ( 1 , 4 ) (1, 4) (1,4) 中,范围内有 3 3 3 个元素,范围外有 1 1 1 个元素;在子数组 ( 5 , 7 ) (5, 7) (5,7) 中,范围内有 2 2 2 个元素,范围外有 1 1 1 个元素;在子数组 ( 8 , 11 ) (8, 11) (8,11) 中,范围内有 3 3 3 个元素,范围外有 1 1 1 个元素。
Given an array a a a of n n n integers, find a range of values [ x , y ] [x, y] [x,y] ( x ≤ y x \le y x≤y), and split a a a into exactly k k k ( 1 ≤ k ≤ n 1 \le k \le n 1≤k≤n) subarrays in such a way that:
Print any solution that minimizes y ? x y - x y?x.
Print any solution that minimizes $ y - x $ .
The input consists of multiple test cases. The first line contains a single integer t t t ( 1 ≤ t ≤ 3 ? 1 0 4 1 \leq t \leq 3 \cdot 10^4 1≤t≤3?104) — the number of test cases. Description of the test cases follows.
The first line of each test case contains two integers n n n and k k k ( 1 ≤ k ≤ n ≤ 2 ? 1 0 5 1 \le k \le n \le 2 \cdot 10^5 1≤k≤n≤2?105) — the length of the array a a a and the number of subarrays required in the partition.
The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1?,a2?,…,an? ( 1 ≤ a i ≤ n 1 \le a_i \le n 1≤ai?≤n) where a i a_i ai? is the i i i-th element of the array.
It is guaranteed that the sum of n n n over all test cases does not exceed 2 ? 1 0 5 2\cdot10^5 2?105.
For each test case, print k + 1 k+1 k+1 lines.
In the first line, print x x x and y y y — the limits of the found range.
Then print k k k lines, the i i i-th should contain l i l_i li? and r i r_i ri? ( 1 ≤ l i ≤ r i ≤ n 1\leq l_i \leq r_i \leq n 1≤li?≤ri?≤n) — the limits of the i i i-th subarray.
You can print the subarrays in any order.
3
2 1
1 2
4 2
1 2 2 2
11 3
5 5 5 1 5 5 1 5 5 5 1
1 2
1 2
2 2
1 3
4 4
5 5
1 1
2 2
3 11
In the first test, there should be only one subarray, which must be equal to the whole array. There are 2 2 2 elements inside the range [ 1 , 2 ] [1, 2] [1,2] and 0 0 0 elements outside, if the chosen range is [ 1 , 1 ] [1, 1] [1,1], there will be 1 1 1 element inside ( a 1 a_1 a1?) and 1 1 1 element outside ( a 2 a_2 a2?), and the answer will be invalid.
In the second test, it is possible to choose the range [ 2 , 2 ] [2, 2] [2,2], and split the array in subarrays ( 1 , 3 ) (1, 3) (1,3) and ( 4 , 4 ) (4, 4) (4,4), in subarray ( 1 , 3 ) (1, 3) (1,3) there are 2 2 2 elements inside the range ( a 2 a_2 a2? and a 3 a_3 a3?) and 1 1 1 element outside ( a 1 a_1 a1?), in subarray ( 4 , 4 ) (4, 4) (4,4) there is only 1 1 1 element ( a 4 a_4 a4?), and it is inside the range.
In the third test, it is possible to choose the range [ 5 , 5 ] [5, 5] [5,5], and split the array in subarrays ( 1 , 4 ) (1, 4) (1,4), ( 5 , 7 ) (5, 7) (5,7) and ( 8 , 11 ) (8, 11) (8,11), in the subarray ( 1 , 4 ) (1, 4) (1,4) there are 3 3 3 elements inside the range and 1 1 1 element outside, in the subarray ( 5 , 7 ) (5, 7) (5,7) there are 2 2 2 elements inside and 1 1 1 element outside and in the subarray ( 8 , 11 ) (8, 11) (8,11) there are 3 3 3 elements inside and 1 1 1 element outside.
以上来自 C o d e F o r c e s ,翻译工具: D e e p L 以上来自CodeForces,翻译工具:DeepL 以上来自CodeForces,翻译工具:DeepL
对于这道题,最根本的问题是最小化的 y ? x y?x y?x,而具体的形式是如何划分整个序列。若同时考虑这两个问题,事情会变得非常复杂,难以下手。所以不妨先扔下具体的形式,去考察最根本的问题。
划分为 k k k 段时,在 [ x , y ] [x,y] [x,y] 内的数总体上至少要比在此区间以外的数多 k k k 个。
因为对于每个段,在区间里的数严格大于不在区间里的数,所以至少大 1 1 1,共 k k k 段,所以至少大 k k k。
于是我们就得到这样一种做法:先将整个序列从小到大排序,然后用一个大小为
n
?
?
n
?
k
2
?
n?\lfloor\frac{n?k}{2}\rfloor
n??2n?k?? 的滑动窗口去检测,窗口两端的数就是
[
x
,
y
]
[x,y]
[x,y],取
y
?
x
y?x
y?x 的最小值即可确定
[
x
,
y
]
[x,y]
[x,y]。
可以发现,让每一段都多一个,可以使滑动窗口尽可能小,这样
y
?
x
y?x
y?x 也会相应更小,同时这样的一组
[
x
,
y
]
[x,y]
[x,y] 一定有可行的划分方案。最后构造方案时也是每一段多一个就划开即可,时间复杂度
O
(
n
)
O(n)
O(n)。注意每次将
A
n
s
w
e
r
Answer
Answer 初始化为极大值。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int Maxn = 200000 + 5;
int n, k, a[Maxn];
int tmp_a[Maxn];
int ans, ansl, ansr;
inline void solve() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
tmp_a[i] = a[i];
}
sort(a + 1, a + 1 + n);
int top = n - (n - k) / 2;
ans = INT_MAX;
for (int i = 1; i <= n && i + top - 1 <= n; i++) {
if (a[i + top - 1] - a[i] < ans) {
ans = a[i + top - 1] - a[i];
ansl = a[i], ansr = a[i + top - 1];
}
}
cout << ansl << " " << ansr << endl;
int tot = 0, st = 1, cnt = 1;
for (int i = 1; i <= n; i++) {
if (ansl <= tmp_a[i] && tmp_a[i] <= ansr) {
tot += 1;
} else {
tot -= 1;
}
if (tot == 1) {
cout << st << " ";
if (cnt == k) {
cout << n << endl;
break;
} else {
cout << i << endl;
tot = 0;
cnt += 1;
st = i + 1;
}
}
}
}
inline void work() {
int T;
cin >> T;
while (T--) {
solve();
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
work();
return 0;
}