「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;
}
分类:
数据结构 / 线段树 / 扫描线
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现