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 ...
随机推荐
- iptables系列教程(一)| iptables入门篇
一个执着于技术的公众号 前言 在早期的 Linux 系统中,默认使用的是 iptables 配置防火墙.尽管新型 的 firewalld 防火墙已经被投入使用多年,但是大量的企业在生产环境中依然出于各 ...
- Android开发的开始
Android 软件 手机软件哦,目前只有一层外壳,进一步功能等待开发. 下载地址
- selenium模块 phantomJs 谷歌无可视界面
参考微博: 什么是selenium 一款基于浏览器自动化的模块 什么是浏览器自动化 通过脚本程序或者python代码,这组程序或者代码表示一些行为动作,selenium可以让这些行为动作映射到浏览器中 ...
- uniapp设置竖屏
//在APP.vue中的onLaunch钩子写入plus.screen.lockOrientation('portrait-primary');
- Codeforces Round #746
挺喜欢这场题目的 A: 水,不写了 B: Hemose Shopping 嘲讽自己一下啦~真的是caii 题意:一个数列,我们通过交换两个点(两点满足距离大于等于\(x\)),问能否排序成功. 思路: ...
- docker 快速上手
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口 安装 docker 设置仓库 $ sudo yum install -y yum-utils $ sudo yum-conf ...
- 面试官:Dubbo是什么,他有什么特性?
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,今天还是过周末,虽然 ...
- C#语言中的类型转换方法(unfinished)
一.C#中的数据类型 1.数值类型 2.字符类型 3.字符串类型 4.布尔类型 5.枚举类型 6.Object类型 二.常见的类型转换 从转换方式的角度,类型转换分为隐式转换与显式转换两种. 其中,隐 ...
- 【Github】 Github访问不是私密连接问题
前言 GitHub是一个软件项目的托管平台,是我们经常需要访问的,我原本在学校时候虽然网速比较慢,但是还以能够满足一些代码下载和上传的,在暑假回到家,再去访问的时候就出现了不能访问的问题. 问题描述 ...
- 【lora无线数传通信模块】亿佰特E22串口模块用于物联网地震预警传感通信方案
物联网地震预警项目介绍: 地震,俗称地动.它像平常的刮风下雨一样,是一种常见的自然现象,是地壳运动的一种表现,即地球内部缓慢积累的能量突然释放而引起的地球表层的振动.据统计,5级以上地震就能够造成破坏 ...