The link to problem:Problem - D - Codeforces
 
D. Range and Partition 
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output

Given an array a of n integers, find a range of values [x,y] (x≤y), and split a into exactly k (1≤k≤n) subarrays in such a way that:

  • Each subarray is formed by several continuous elements of aa, that is, it is equal to al,al+1,…,ar for some l and r (1≤l≤r≤n).
  • Each element from aa belongs to exactly one subarray.
  • In each subarray the number of elements inside the range [x,y] (inclusive) is strictly greater than the number of elements outside the range. An element with index i is inside the range [x,y] if and only if x≤ai≤y.

Print any solution that minimizes y−x.

Input

The input consists of multiple test cases. The first line contains a single integer tt (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 and k (1≤k≤n≤2⋅105) — the length of the array a and the number of subarrays required in the partition.

The second line of each test case contains nn integers a1,a2,…,an (1≤ai≤n) where ai is the i-th element of the array.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output

For each test case, print k+1 lines.

In the first line, print x and y — the limits of the found range.

Then print k lines, the i-th should contain li and ri (1≤li≤ri≤n) — the limits of the i-th subarray.

You can print the subarrays in any order.

Example
input
3
2 1
1 2
4 2
1 2 2 2
11 3
5 5 5 1 5 5 1 5 5 5 1
output
1 2
1 2
2 2
1 3
4 4
5 5
1 1
2 2
3 11
Note

In the first test, there should be only one subarray, which must be equal to the whole array. There are 2 elements inside the range [1,2] and 0 elements outside, if the chosen range is [1,1], there will be 1 element inside (a1) and 1 element outside (a2), and the answer will be invalid.

In the second test, it is possible to choose the range [2,2], and split the array in subarrays (1,3) and (4,4), in subarray (1,3) there are 2 elements inside the range (a2 and a3) and 1 element outside (a1), in subarray (4,4) there is only 1 element (a4), and it is inside the range.

In the third test, it is possible to choose the range [5,5], and split the array in subarrays (1,4), (5,7) and (8,11), in the subarray (1,4) there are 3 elements inside the range and 1 element outside, in the subarray (5,7) there are 2 elements inside and 1 element outside and in the subarray (8,11) there are 3 elements inside and 1 element outside.

题目大意:

确定x,y,满足条件:使得数组中元素可以分为正好k个子数组,使得每个子数组中,在[x,y]内的元素个数严格大于在[x,y]之外的元素个数。

要求y-x的值最小。

思路:思维 + 贪心 + 二分查找

 首先,当x,y确定时,要保证可以分为符合题意的k个数组,只需要满足以下条件:数组中在[x,y]内的元素个数cnt1,以及在范围外的元素个数cnt2,cnt1 - cnt2 >= k。

证明:不妨设b[i], 当a[i]在区间内时,b[i] = 1, 否则b[i] = -1, 对于数组b求前缀和:当pre[i] = 1时,可以第1次分割数组;当pre[i] = 2时,可以第2次分割数组;……;当pre[i] = k时,可以第k次分割数组。那么,只要pre[n] >= k,这样的x,y就必定满足题意。

 接下来,考虑如何如何使 y - x 的值最小:将原数组复制一份并排序(得到数组b),枚举左边界x,二分查找符合(1)的右边界y,并动态更新x,y, 使得y - x尽量小。设数组b中大于等于x的第一个下标为 l,则查找到的下标 r,应满足:(r - l + 1) - [ n - (r - l + 1) ] >= k。

代码:

 1 //Jakon:
2 #include <bits/stdc++.h>
3 #define int long long
4 using namespace std;
5 const int N = 200010;
6
7 int test, n, k, a[N], b[N], x, y;
8
9 void solve()
10 {
11 sort(b+1, b+1+n); // 排序后可二分查找
12 int ans = b[n] - b[1] + 1;
13 x = b[1], y = b[n];
14 for(int i = b[1]; i <= b[n]; i++)
15 {
16 int l = lower_bound(b+1, b+1+n, i) - b;
17 int len = (n + k + 1) >> 1; // len - (n-len) >= k
18 if(l+len-1 > n) continue;
19 int xx = b[l], yy = b[l+len-1];
20 if(yy - xx < ans) ans = yy - xx, x = xx, y = yy;
21 }
22 int now = 0, l = 1, r = 0, cnt = 0;
23 printf("%lld %lld\n", x, y);
24 for(int i = 1; i <= n; i++)
25 {
26 r ++;
27 if(x <= a[i] && a[i] <= y) now += 1;
28 else now -= 1;
29 if(now == 1 && cnt != k-1)
30 {
31 printf("%lld %lld\n", l, r);
32 now = 0, l = i + 1, cnt ++;
33 }
34 }
35 printf("%lld %lld\n", l, r);
36 cout << endl;
37 }
38
39 signed main()
40 {
41 cin >> test;
42 while(test--)
43 {
44 cin >> n >> k;
45 for(int i = 1; i <= n; i++) scanf("%lld", &a[i]), b[i] = a[i];
46 solve();
47 }
48
49 return 0;
50 }

Codeforces Round #768 (Div. 2) D. Range and Partition // 思维 + 贪心 + 二分查找的更多相关文章

  1. Codeforces Round #521 (Div. 3) E. Thematic Contests(思维)

    Codeforces Round #521 (Div. 3)  E. Thematic Contests 题目传送门 题意: 现在有n个题目,每种题目有自己的类型要举办一次考试,考试的原则是每天只有一 ...

  2. Codeforces Round #373 (Div. 2) C. Efim and Strange Grade —— 贪心 + 字符串处理

    题目链接:http://codeforces.com/problemset/problem/719/C C. Efim and Strange Grade time limit per test 1 ...

  3. Codeforces Round #379 (Div. 2) C. Anton and Making Potions 枚举+二分

    C. Anton and Making Potions 题目连接: http://codeforces.com/contest/734/problem/C Description Anton is p ...

  4. Codeforces Round #381 (Div. 2) D. Alyona and a tree 树上二分+前缀和思想

    题目链接: http://codeforces.com/contest/740/problem/D D. Alyona and a tree time limit per test2 secondsm ...

  5. Codeforces Round #342 (Div. 2) B. War of the Corporations 贪心

    B. War of the Corporations 题目连接: http://www.codeforces.com/contest/625/problem/B Description A long ...

  6. Codeforces Round #327 (Div. 2) D. Chip 'n Dale Rescue Rangers 二分 物理

    D. Chip 'n Dale Rescue Rangers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/co ...

  7. Codeforces Round #532 (Div. 2) F 线性基(新坑) + 贪心 + 离线处理

    https://codeforces.com/contest/1100/problem/F 题意 一个有n个数组c[],q次询问,每次询问一个区间的子集最大异或和 题解 单问区间子集最大异或和,线性基 ...

  8. Codeforces Round #548 (Div. 2) F splay(新坑) + 思维

    https://codeforces.com/contest/1139/problem/F 题意 有m个人,n道菜,每道菜有\(p_i\),\(s_i\),\(b_i\),每个人有\(inc_j\), ...

  9. Codeforces Round #396 (Div. 2) B. Mahmoud and a Triangle 贪心

    B. Mahmoud and a Triangle 题目连接: http://codeforces.com/contest/766/problem/B Description Mahmoud has ...

随机推荐

  1. CEPH-5:ceph集群基本概念与管理

    ceph集群基本概念与管理 ceph集群基本概念 ceph集群整体结构图 名称 作用 osd 全称Object Storage Device,主要功能是存储数据.复制数据.平衡数据.恢复数据等.每个O ...

  2. 轮播——swiper

    swiper组件 1.轮播数据是使用ajax进行填充的话,可能数目是0~n,在数目是1时,轮播会出现一些问题(出现空白侧),这时需作出判断(一张图片不滑动,多张就就行滑动),方法如下(以下方法中,si ...

  3. TCP 协议有哪些缺陷?

    作者:小林coding 图解计算机基础网站:https://xiaolincoding.com 大家好,我是小林. 忽然思考一个问题,TCP 通过序列号.确认应答.超时重传.流量控制.拥塞控制等方式实 ...

  4. JWT 访问令牌

    JWT 访问令牌 更为详细的介绍jwt 在学习jwt之前我们首先了解一下用户身份验证 1 单一服务器认证模式 一般过程如下: 用户向服务器发送用户名和密码. 验证服务器后,相关数据(如用户名,用户角色 ...

  5. 【单片机】NB-IoT移远BC28调试笔记

    一.入网总体思路 入网思路是参考 <Quectel_BC95&BC35-G&BC28_应用设计指导_V1.1.pdf>来做的.流程如图所示: 二.具体调试细节3.1 AT+ ...

  6. .NET性能优化-推荐使用Collections.Pooled(补充)

    简介 在上一篇.NET性能优化-推荐使用Collections.Pooled一文中,提到了使用Pooled类型的各种好处,但是在群里也有小伙伴讨论了很多,提出了很多使用上的疑问. 所以特此写了这篇文章 ...

  7. 爬取豆瓣TOP250电影

    自己跟着视频学习的第一个爬虫小程序,里面有许多不太清楚的地方,不如怎么找到具体的电影名字的,那么多级关系,怎么以下就找到的是那个div呢? 诸如此类的,有许多,不过先做起来再说吧,后续再取去弄懂. i ...

  8. ACL权限控制

    ALC讲述比较详细 https://zhuanlan.zhihu.com/p/360158311

  9. electron-vue 项目启动动态获取配置文件中的后端服务地址

    前言 最近的项目迭代中新增一个需求,需要在electron-vue 项目打包之后,启动exe 可执行程序的时候,动态获取配置文件中的 baseUrl 作为服务端的地址.electron 可以使用 no ...

  10. 在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式

    在进行项目开发的时候,刚好需要用到对字符串表达式进行求值的处理场景,因此寻找了几个符合要求的第三方组件LambdaParser.DynamicExpresso.Z.Expressions,它们各自功能 ...