CF1341B Nastya and Door 题解

题目

链接

https://www.luogu.com.cn/problem/CF1341B

字面描述

题面翻译

给定一个长度为 n n n 的数组 a i ai ai。定义一个位置 i i i 是“峰”,当且仅当 a i − 1 ≤ a i ≥ a i + 1 a_i−1≤a_i≥a_i+1 ai1aiai+1

求长度为 k k k 的区间中含有“峰”个数最多的区间。

多测.

1 ≤ t ≤ 104 1≤t≤104 1t104

3 ≤ k ≤ n ≤ 2 × 105 3≤k≤n≤2×105 3kn2×105

0 ≤ a i ≤ 109 0≤ai≤109 0ai109

∑ n ≤ 2 × 105 ∑n≤2×105 n2×105

题目描述

On February 14 Denis decided to give Valentine to Nastya and did not come up with anything better than to draw a huge red heart on the door of the length $ k $ ( $ k \ge 3 $ ). Nastya was very confused by this present, so she decided to break the door, throwing it on the mountains.

Mountains are described by a sequence of heights $ a_1, a_2, \dots, a_n $ in order from left to right ( $ k \le n $ ). It is guaranteed that neighboring heights are not equal to each other (that is, $ a_i \ne a_{i+1} $ for all $ i $ from $ 1 $ to $ n-1 $ ).

Peaks of mountains on the segment $ [l,r] $ (from $ l $ to $ r $ ) are called indexes $ i $ such that $ l < i < r $ , $ a_{i - 1} < a_i $ and $ a_i > a_{i + 1} $ . It is worth noting that the boundary indexes $ l $ and $ r $ for the segment are not peaks. For example, if $ n=8 $ and $ a=[3,1,4,1,5,9,2,6] $ , then the segment $ [1,8] $ has only two peaks (with indexes $ 3 $ and $ 6 $ ), and there are no peaks on the segment $ [3, 6] $ .

To break the door, Nastya throws it to a segment $ [l,l+k-1] $ of consecutive mountains of length $ k $ ( $ 1 \le l \le n-k+1 $ ). When the door touches the peaks of the mountains, it breaks into two parts, after that these parts will continue to fall in different halves and also break into pieces when touching the peaks of the mountains, and so on. Formally, the number of parts that the door will break into will be equal to $ p+1 $ , where $ p $ is the number of peaks on the segment $ [l,l+k-1] $ .

Nastya wants to break it into as many pieces as possible. Help her choose such a segment of mountains $ [l, l+k-1] $ that the number of peaks on it is maximum. If there are several optimal segments, Nastya wants to find one for which the value $ l $ is minimal.

Formally, you need to choose a segment of mountains $ [l, l+k-1] $ that has the maximum number of peaks. Among all such segments, you need to find the segment that has the minimum possible value $ l $ .

输入格式

The first line contains an integer $ t $ ( $ 1 \leq t \leq 10^4 $ ) — the number of test cases. Then the descriptions of the test cases follow.

The first line of each test case contains two integers $ n $ and $ k $ ( $ 3 \leq k \leq n \leq 2 \cdot 10^5 $ ) — the number of mountains and the length of the door.

The second line of the input data set contains $ n $ integers $ a_1, a_2, \dots, a_n $ ( $ 0 \leq a_i \leq 10 ^ 9 $ , $ a_i \neq a_{i + 1} $ ) — the heights of mountains.

It is guaranteed that the sum of $ n $ over all the test cases will not exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output two integers $ t $ and $ l $ — the maximum number of parts that the door can split into, and the left border of the segment of length $ k $ that the door should be reset to.

样例 #1

样例输入 #1
5
8 6
1 2 4 1 2 4 1 2
5 3
3 2 3 2 1
10 4
4 3 4 3 2 3 2 1 0 1
15 7
3 7 4 8 2 3 4 5 21 2 3 4 2 1 3
7 5
1 2 3 4 5 6 1
样例输出 #1
3 2
2 2
2 1
3 1
2 3

提示

In the first example, you need to select a segment of mountains from $ 2 $ to $ 7 $ . In this segment, the indexes $ 3 $ and $ 6 $ are peaks, so the answer is $ 3 $ (only $ 2 $ peaks, so the door will break into $ 3 $ parts). It is not difficult to notice that the mountain segments $ [1, 6] $ and $ [3, 8] $ are not suitable since they only have a $ 1 $ peak (for the first segment, the $ 6 $ index is not a peak, and for the second segment, the $ 3 $ index is not a peak).

In the second example, you need to select a segment of mountains from $ 2 $ to $ 4 $ . In this segment, the index $ 3 $ is a peak, so the answer is $ 2 $ (only $ 1 $ peak, so the door will break into $ 2 $ parts).

In the third example, you need to select a segment of mountains from $ 1 $ to $ 4 $ . In this segment, the index $ 3 $ is a peak, so the answer is $ 2 $ (only $ 1 $ peak, so the door will break into $ 2 $ parts). You can see that on the segments $ [2, 5] $ , $ [4, 7] $ and $ [5, 8] $ the number of peaks is also $ 1 $ , but these segments have a left border greater than the segment $ [1, 4] $ , so they are not the correct answer.

小建议

看英文版题目,中文版翻译的少了很多细节甚至有错。

思路

典型的固定长度子序列的前缀和问题,主要记录峰的数量,打擂台留峰最多且角标最小的,最后直接+1(求被峰隔断的数量)。

还需要注意到的问题是峰的构成由峰本身和相邻的两个元素构成缺一不可,所以求区间和时,要2边元素下标向区间缩小1

代码实现

#include<bits/stdc++.h>
using namespace std;

const int maxn=2e5+10;
int t,n,k,l,ans;
int a[maxn],x[maxn],f[maxn];
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&k);
		ans=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			x[i]=0;
		}
		//记录峰
		for(int i=2;i<n;i++){
			if(a[i]>=a[i-1]&&a[i]>=a[i+1])x[i]=1;
		}
		//求峰的前缀和
		for(int i=1;i<=n;i++)f[i]=f[i-1]+x[i];
		//打擂台
		for(int i=1;i<=n-k+1;i++){
			int p=f[i+k-2]-f[i]+1;//向区间内部缩1
			if(p>ans){
				l=i;
				ans=p;
			} 
		} 
		printf("%d %d\n",ans,l);
	} 
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

materialistOier

我只是一名ssfoier

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值