牛客 小y的序列 (双指针 , 线段树)

image

image

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);
//#pragma GCC optimize(3,"Ofast","inline")
typedef long long ll;
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
int a[N];
struct node{
    int mx, mi;
}tree[N << 2];
void pushup(int rt) {
    tree[rt].mx = max(tree[rt << 1].mx, tree[rt << 1 | 1].mx);
    tree[rt].mi = min(tree[rt << 1].mi, tree[rt << 1 | 1].mi);
}
void build(int l, int r, int rt) {
    if(l == r) {
        tree[rt].mx = tree[rt].mi = a[l];
        return;
    }
    int mid = l + r >> 1;
    build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1);
    pushup(rt);
}
pair<int, int> query(int a, int b, int l, int r, int rt) {
    if(b < l || a > r) return {0x3f3f3f3f, 0};
    if(a <= l && r <= b) return {tree[rt].mi, tree[rt].mx};
    int mid = l + r >> 1;
    pair<int, int> res;
    pair<int, int> q1 = query(a, b, l, mid, rt << 1);
    pair<int, int> q2 = query(a, b, mid + 1, r, rt << 1 | 1);
    res.first = min(q1.first, q2.first);
    res.second = max(q1.second, q2.second);
    return res; 
}
int main() {
    int n, k; cin >> n >> k;
    for (int i = 1; i <= n; ++ i) cin >> a[i];
    build(1, n, 1);
    int l = 1, r1 = 1, r2 = 1; ll ans = 0;
    for (; l <= n; ++ l) {
        pair<int, int> qry = query(l, r1, 1, n, 1);
        while( r1 <= n && qry.second - qry.first < k ) ++ r1, qry = query(l, r1, 1, n, 1);
        qry = query(l, r2, 1, n, 1); //这里<= 使得凑不够k时,r2,r1都跑到最后,否则r1
        //可能在r2后面
        while( r2 <= n && qry.second - qry.first <= k ) ++ r2, qry = query(l, r2, 1, n, 1);
        -- r2;
        if(r1 <= n) ans += r2 - r1 + 1;
        else break;
    }
    cout << ans << endl;
    return 0;
}
posted @ 2022-03-25 21:15  qingyanng  阅读(16)  评论(0编辑  收藏  举报