洛谷 B3667 求区间所有后缀最大值的位置 的题解

题目大意

传送门

大体思路

由数据范围和大概的题意不难知道这题用的是单调队列。

但是好多大佬直接用 deque 秒杀了这题,但是其实可以有更优的方法,于是 给出一种不用 STL,且空间小、代码简短的近似于单调队列模板的方式。

定义 h e a d head head t a i l tail tail 分别维护这个单调队列的头和尾。每次读入的循环里保持 k k k 的间距,按照题意模拟即可。最后的答案即 t a i l − h e a d tail - head tailhead

注意点:

  • 第一个 while 循环完后 q h e a d q_{head} qhead 依然是不小于 l l l 的,因此后面一定要 head--

  • 当一次循环开始我们要求左端点时, i − k + 1 i - k + 1 ik+1 必须对 1 1 1 取最大值,不然如果 i < k i < k i<k,左端点就会是负数,不满足题意。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
inline ll read() {
	ll x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); }
	while(ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); }
	return x * f;
}
int n, k, head = 1, tail = 0, q[1000007];
ll a[1000007];
int main() {
	n = read(), k = read();
	for(int i = 1; i <= n; i++) {
		a[i] = read();
		int l = max(1, i - k + 1), r = i;
		while(head < tail && q[head] < l) head++; head--;
		while(head < tail && a[q[tail]] <= a[i]) tail--;
		q[++tail] = i;
		if(i >= k) printf("%d\n", tail - head);
	}	
	return 0;
}
  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值