Codeforces Round #768 (Div. 2) D. Range and Partition // 思维 + 贪心 + 二分查找
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.
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.
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.
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 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 // 思维 + 贪心 + 二分查找的更多相关文章
- Codeforces Round #521 (Div. 3) E. Thematic Contests(思维)
Codeforces Round #521 (Div. 3) E. Thematic Contests 题目传送门 题意: 现在有n个题目,每种题目有自己的类型要举办一次考试,考试的原则是每天只有一 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- Codeforces Round #532 (Div. 2) F 线性基(新坑) + 贪心 + 离线处理
https://codeforces.com/contest/1100/problem/F 题意 一个有n个数组c[],q次询问,每次询问一个区间的子集最大异或和 题解 单问区间子集最大异或和,线性基 ...
- Codeforces Round #548 (Div. 2) F splay(新坑) + 思维
https://codeforces.com/contest/1139/problem/F 题意 有m个人,n道菜,每道菜有\(p_i\),\(s_i\),\(b_i\),每个人有\(inc_j\), ...
- 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 ...
随机推荐
- QT快速入门
QT快速入门 本文档将介绍QT工程的创建.UI界面布局,并以计数器为例了解QT中多线程的用法,最终完成一个基础的QT项目. 1 创建QT工程文件 在安装好QT之后,能够在其安装组件中找到Qt Crea ...
- Dapr 不是服务网格,只是我长的和他很像
概述 我们快速看一遍官方文档:https://docs.dapr.io/concepts/service-mesh/#how-dapr-and-service-meshes-compare ,看看 D ...
- JUC的数据库连接池小练习
JUC练习数据库连接池实现 通过一个连接数组来充当连接池 一个原子的标记数组 通过cas来保持多线程下的安全,用synchronized来进行暂停和唤醒 @Slf4j public class MyC ...
- strlen获取字符数组为什么是255
为什么是255呢? strlen函数的规则是,读取到0则判断字符串结束. char为1字节,只有8位. 所以...... -1就是 1111 1111, -2就是 1111 1110, 直到-128: ...
- MongoDB 设置用户和密码
每日一句 Zeal without knowledge is fire without light. 没有知识的热忱犹如火之无光. 给每个数据库设置单独的管理员 我们除了可以设置数据库的超级管理员以外 ...
- 【Golang】创建有配置参数的结构体时,可选参数应该怎么传?
写在前面的话 Golang中构建结构体的时候,需要通过可选参数方式创建,我们怎么样设计一个灵活的API来初始化结构体呢. 让我们通过如下的代码片段,一步一步说明基于可选参数模式的灵活 API 怎么设计 ...
- Linux服务器安装图形化界面
Linux服务器安装图形化界面 1.检查有无安装gnome桌面 [root@localhost ~]# rpm -qa |grep gnome 2.查看可安装组件列表 [root@localhost ...
- Lucene从入门到实战
Lucene 在了解Lucene之前,我们先了解下全文数据查询. 全文数据查询 我们的数据一般分为两种:结构化数据和非结构化数据 结构化数据:有固定格式或有限长度的数据,如数据库中的数据.元数据 非结 ...
- Vscode标题栏出现【不受支持】提示的完美解决方案
安装Fix VSCode Checksums code --install-extension lehni.vscode-fix-checksums 打开命令面板,快捷键 Ctrl + Shift + ...
- 重学ES系列之过滤数组
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...