「CF407E」k-d-sequence(待更新)

/*
address:https://codeforces.com/problemset/problem/407/E
AC 2025/2/4 20:18
*/
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, k, d, a[N];
struct SegmentTree {
#define ls (id << 1)
#define rs (id << 1 | 1)
#define mid (l + r >> 1)
    int add[N << 2], val[N << 2];
    inline void merge(int id) { val[id] = min(val[ls], val[rs]); }
    inline void pushdown(int id) {
        if (add[id]) {
            add[ls] += add[id];add[rs] += add[id];
            val[ls] += add[id];val[rs] += add[id];
            add[id] = 0;
        }
    }
    inline void build(int id, int l, int r) {
        if (l == r) {
            val[id] = l;
            return;
        }
        build(ls, l, mid);build(rs, mid + 1, r);
        merge(id);
    }
    inline void modify(int id, int l, int r, int L, int R, int k) {
        if (l >= L && R >= r) {
            add[id] += k;val[id] += k;
            return;
        }
        pushdown(id);
        if (L <= mid) modify(ls, l, mid, L, R, k);
        if (R > mid) modify(rs, mid + 1, r, L, R, k);
        merge(id);
    }
    inline void change(int id, int l, int r, int x) {
        if (l == r) {
            val[id] = 0;
            return;
        }
        pushdown(id);
        if (x <= mid) change(ls, l, mid, x);
        else change(rs, mid + 1, r, x);
        merge(id);
    }
    inline int get(int id, int l, int r, int k) {
        if (l == r) return l;
        pushdown(id);
        if (val[ls] <= k) return get(ls, l, mid, k);
        else return get(rs, mid + 1, r, k);
    }
    inline int query(int id, int l, int r, int L, int R, int k) {
        if (l >= L && R >= r) {
            if (val[id] <= k) return get(id, l, r, k);
            return -1;
        }
        pushdown(id);
        int ret = -1;
        if (L <= mid) ret = query(ls, l, mid, L, R, k);
        if (ret == -1 && R > mid) ret = query(rs, mid + 1, r, L, R, k);
        return ret;
    }
}SGT;
map<int, int>last;
int stk_up[N], top_up, stk_dn[N], top_dn;
int main() {
    // freopen("seq-06.in", "r", stdin);
    // freopen("seq-06.out", "w", stdout);
    scanf("%d%d%d", &n, &k, &d);
    for (int i = 1;i <= n;i++) scanf("%d", &a[i]), a[i] += 1e9;
    if (d == 0) {
        int l = 1, L = 1, R = 1;
        for (int r = 2;r <= n;r++) {
            if (a[r] != a[r - 1]) l = r;
            if (r - l > R - L) R = r, L = l;
        }
        printf("%d %d\n", L, R);
        return 0;
    }
    SGT.build(1, 1, n);
    int L = 1, R = 1, j = 1;
    for (int i = 1;i <= n;i++) {
        int _j = j;
        if (a[i] % d != a[i - 1] % d) j = i;
        else j = max(j, last[a[i]] + 1);
        last[a[i]] = i;
        for (;_j < j;_j++) SGT.change(1, 1, n, _j);
        while (top_up > 0 && stk_up[top_up] >= j && a[stk_up[top_up]] >= a[i]) {
            SGT.modify(1, 1, n, max(j, stk_up[top_up - 1] + 1), stk_up[top_up], a[stk_up[top_up]] / d);
            top_up--;
        }
        SGT.modify(1, 1, n, max(j, stk_up[top_up] + 1), i, -a[i] / d);
        stk_up[++top_up] = i;
        while (top_dn > 0 && stk_dn[top_dn] >= j && a[stk_dn[top_dn]] <= a[i]) {
            SGT.modify(1, 1, n, max(j, stk_dn[top_dn - 1] + 1), stk_dn[top_dn], -a[stk_dn[top_dn]] / d);
            top_dn--;
        }
        SGT.modify(1, 1, n, max(j, stk_dn[top_dn] + 1), i, a[i] / d);
        stk_dn[++top_dn] = i;
        int l = SGT.query(1, 1, n, j, i, k + i);
        if (l != -1 && i - l > R - L) R = i, L = l;
    }
    printf("%d %d\n", L, R);
    return 0;
}
posted @   keysky  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示