当前位置:   article > 正文

【牛客竞赛】King of Range题解_给定 n 个整数,以及 q 次询问。 每次询问给出一个整数 k ,请问这些整数能分别

给定 n 个整数,以及 q 次询问。 每次询问给出一个整数 k ,请问这些整数能分别

题目大意

给定一个 n n n个数的序列 a i a_i ai。有 q q q次询问,每次询问是一个非负整数 k k k,求出有多少对 ( l , r ) (l, r) (l,r),满足 m a x ( a [ i ] ) − m i n ( a [ j ] ) > k max(a[i]) - min(a[j]) > k max(a[i])min(a[j])>k,其中 l ≤ i , j ≤ r l\le i, j \le r li,jr
题目链接

思路

不难发现满足要求的序列有单调性,即如果当前区间满足最大值减去最小值大于k,那么包含这个区间的更大的区间,也一定满足

而这一类问题,通常可以采用尺取法。即:

  • 我们先固定起点 l l l,然后让 r r r l l l开始一个一个往后走,并记录最大值与最小值。
  • 一旦当前序列满足了条件,那么选取 r r r之后的点作为结尾,也一定会满足,所以直接让答案 a n s + = n − r + 1 ans += n - r + 1 ans+=nr+1,然后让 l l l后移动一位
  • 因为 r r r在恰好满足条件的时候就不在移动了,所以 l l l在往后移动一位的时候,满足条件的结尾一定在 r r r点或之后,所以 r r r的起点还是当前位置,然后继续按照第一步继续,直到统计完成。
  • 因为我们需要记录区间的最大值和最小值,所以我们可以用两个单调队列来统计,即统计最大值的时候,如果新加入的数 X X X比当前的数 Y Y Y要大,那么就让 Y Y Y​​出队,因为X比Y大还比它靠后,意味着在取最大值的时候,只要有X在,就永远不会取到Y,而X又在Y之后,也就是说它出队也晚于Y,所以Y就没有存在的必要了~~(惨 Y 惨)~~

代码

#include <cstdio>
#include <iostream>
#include <deque>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxN = 1e5 + 7;
typedef long long ll;

int m, n, a[maxN];

ll calc(ll k)
{
    deque<int> maxPos, minPos;
    int l = 1,r = 0;
    ll ans = 0;
    while(l <= n && r <= n) {
        while((!maxPos.empty()) && maxPos.front() < l)
            maxPos.pop_front();
        while((!minPos.empty()) && minPos.front() < l)
            minPos.pop_front();
        if((!maxPos.empty()) && a[maxPos.front()] - a[minPos.front()] > k) {
            ans += n - r + 1;
            ++l;
            continue;
        }
        else {
            ++r;
            while(!maxPos.empty() && a[maxPos.back()] <= a[r])
                maxPos.pop_back();
            maxPos.push_back(r);
            while(!minPos.empty() && a[minPos.back()] >= a[r])
                minPos.pop_back();
            minPos.push_back(r);
        }
    }
    return ans;
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for(int i = 1; i <= m; ++i) {
        int k;
        scanf("%d", &k);
        printf("%lld\n", calc(k));
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/560756
推荐阅读
相关标签
  

闽ICP备14008679号