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 ...
随机推荐
- 面试官问:浏览器输入 URL 回车之后发生了什么?
一个执着于技术的公众号 前言 这个问题已经是老生常谈了,更是经常被作为面试的压轴题出现,网上也有很多文章,但最近闲的无聊,然后就自己做了一篇笔记,感觉比之前理解更透彻了. 注意:本文的步骤是建立在,请 ...
- Swift服务的基本使用
swift概述 Swift 最初是由Rackspace公司开发的高可用分布式对象存储服务,并于2010年贡献给OpenStack开源社区作为其最初的核心子项目之一,为其Nova子项目提供虚机镜像存储服 ...
- vue - Vue脚手架/消息订阅与发布
今天的内容有意思了,朋友们继续对我们之前的案例完善,是这样的我们之前是不是靠props来完成父给子,子给父之间传数据,其实父给子最好的方法就是props但是自给父就不是了,并且今天学下来,不仅如此,组 ...
- zabbix5.0报错PHP时区未设置(配置参数"date.timezone")
解决办法 : #1.编辑文件/etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf,取消注释并设置为所在地时区 vim /etc/opt/rh/rh-php72/php- ...
- MySQL8小时问题
一.问题 获取MySQL连接,8小时内无请求自动断开连接. 二.解决 2.1 分析 MySQL服务器默认的"wait_timeout"是28800秒即8小时,意味着如果一个连接的空 ...
- SpringSecurity的 loginProcessingUrl为什么不能用
前情提要: 我在做一个springsecurity动态鉴权的项目时, 据网上说配置了 loginProcessingUrl("/login1"); 以后 就可以自定义login的请 ...
- docker安装nginx,配置SSL
nginx安装 下载镜像并测试 1.docker pull nginx 2.docker images nginx 查看我们拉取到本地的nginx镜像IMAGE ID 3.首先测试下nginx镜像是否 ...
- KALI2020忘记用户名和密码
时隔半年,打开kali发现忘记了自己精心研制的用户名密码......... 第一步 在开机的时候就按e键进入如下界面 第二步 用键盘上的上下箭头↑↓进行屏幕滚动,滑到最后一行发现修改目标 倒数第四行: ...
- npm发布包以及更新包还有需要注意的几点问题(这里以发布vue插件为例)
前言 在此之前,你需要去npm官网注册一个属于自己的账号,记住自己的账户名以及密码.邮箱,后面会用的到.第一步,安装webpack简易框架 vue init webpack-simple marque ...
- Vue.js与Node.js一起打造一款属于自己的音乐App(收藏)
更多内容请见原文,原文转载自:https://blog.csdn.net/weixin_44519496/article/details/118755888