2021暑假牛客多校_K.King of Range(双指针尺取)

本文介绍了一种解决特定区间查询问题的方法——尺取法。针对给出的序列,通过高效的算法计算满足条件max-min>k的区间数量,并处理多个询问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

K.King of Range

题目传送门:

题目传送门

题面:

在这里插入图片描述

题目大意:

给出一个大小为 n n n 的序列,找出 m a x − m i n > k m a x − m i n > k maxmin>k的区间个数。
m m m个询问,对于每个询问给定一个常数 k k k,输出区间个数。

思路:

尺取。

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 2e7 + 9;
int a[maxn];
int up[maxn];
int down[maxn];

int main() {
    int n, m, k;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    while (m--) {
        cin >> k;
        int hh = 0, tt = -1, hh1 = 0, tt1 = -1, cnt = 1;
        ll ans = 0;
        for (int i = 1; i <= n; i++) {
            while (hh <= tt && a[up[tt]] <= a[i])tt--;
            up[++tt] = i;
            while (hh1 <= tt1 && a[down[tt1]] >= a[i])tt1--;
            down[++tt1] = i;
            while (i >= cnt && a[up[hh]] - a[down[hh1]] > k) {
                ans += (n - i) + 1;
                cnt++;
                if (cnt > up[hh])hh++;
                if (cnt > down[hh1])hh1++;
            }
        }
        cout << ans << endl;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值