尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

CF407E k-d-sequence 题目分析(0929模拟赛最后一题)

CF407E k-d-sequence 题目分析(0929模拟赛最后一题)
📅 发布时间:2026/6/19 15:05:33
首先特判 $d=0$ 的情况。好,对于 $d\geq 1$ 的情况考虑转化。注意到等差序列满足: - 模 $d$ 同余。 - 值两两不同。我们先把 $a$ 变为正数,然后全部除以 $d$,这肯定是正确的,你可以想一想。那么我们就全部转化为了 $d=1$ 的情况。考虑符合条件的序列 $[l,r]$ 满足什么: - $\max_{i\in[l,r]}a_i-\min_{i\in[l,r]}a_i-1-(r-l+1-2)\leq k$。 - $[l,r]$ 内没有元素重复。先考虑没有重复的情况:直接记录每个值之前出现最晚的位置。考虑枚举 $r$,使得最左的 $l$ 满足条件,且 $l\in[x+1,r]$,其中 $x$ 表示 $a_r$ 上次出现的位置。那么我们只需要使:$\max(l,r)-min(l,r)+l\leq k+r$ 即可。那么我们如何维护这种东西呢?注意 $\max,\min$ 用单调栈是好维护的。

题目描述

我们称一组整数序列为好的 \(k\)-\(d\) 序列,是指我们最多可以向序列中插入 \(k\) 个数,使得排序后该序列成为公差为 \(d\) 的等差数列。

你得到了一个由 \(n\) 个整数构成的序列 \(a\),你的任务是找到该序列的最长连续子段,使其是一个好的 \(k\)-\(d\) 序列。

分析

好题,套路题目。

一道类似的题目为:CF526F Pudding Monsters。

最后是同样的处理方式。

好了,步入正题。

首先特判 \(d=0\) 的情况。

好,对于 \(d\geq 1\) 的情况考虑转化。

注意到等差序列满足:

  • 模 \(d\) 同余。
  • 值两两不同。

我们先把 \(a\) 变为正数,然后全部除以 \(d\),这肯定是正确的,你可以想一想。

那么我们就全部转化为了 \(d=1\) 的情况。

考虑符合条件的序列 \([l,r]\) 满足什么:

  • \(\max_{i\in[l,r]}a_i-\min_{i\in[l,r]}a_i-1-(r-l+1-2)\leq k\)。
  • \([l,r]\) 内没有元素重复。

先考虑没有重复的情况:直接记录每个值之前出现最晚的位置。

考虑枚举 \(r\),使得最左的 \(l\) 满足条件,且 \(l\in[x+1,r]\),其中 \(x\) 表示 \(a_r\) 上次出现的位置。

那么我们只需要使:\(\max(l,r)-min(l,r)+l\leq k+r\) 即可。

那么我们如何维护这种东西呢?

注意 \(\max,\min\) 用单调栈是好维护的。

怎么维护呢?

考虑维护单调栈,栈中的每个点代表一段区间,它们的 \(\max\) 是这个栈中的元素,每次弹出时修改即可。

操作是区间加减,查询区间最左侧小于等于某个数的位置。

代码

时间复杂度 \(\mathcal{O}(n\log n)\)。

#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <unordered_map>
#define int long long
#define N 200005
using namespace std;
struct tree{int minval,pos;
}tr[N << 2];
int lz[N << 2];
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
void pushup(int x) {if (tr[ls(x)].minval < tr[rs(x)].minval) tr[x].pos = tr[ls(x)].pos;else if (tr[ls(x)].minval > tr[rs(x)].minval) tr[x].pos = tr[rs(x)].pos;else tr[x].pos = min(tr[ls(x)].pos,tr[rs(x)].pos);tr[x].minval = min(tr[ls(x)].minval,tr[rs(x)].minval);
}
void pushdown(int x) {tr[ls(x)].minval += lz[x],tr[rs(x)].minval += lz[x];lz[ls(x)] += lz[x],lz[rs(x)] += lz[x];lz[x] = 0;
}
void build(int x,int l,int r) {lz[x] = 0;if (l == r) return tr[x].minval = tr[x].pos = l,void();int mid = l + r >> 1;build(ls(x),l,mid),build(rs(x),mid + 1,r);pushup(x);
}
void update(int x,int l,int r,int L,int R,int val) {if (l > R || r < L) return;if (L <= l && r <= R) {tr[x].minval += val;lz[x] += val;return;}if (lz[x]) pushdown(x);int mid = l + r >> 1;update(ls(x),l,mid,L,R,val),update(rs(x),mid + 1,r,L,R,val);pushup(x);
}
int query(int x,int l,int r,int L,int R,int val) {if (l > R || r < L) return -1;if (tr[x].minval > val) return -1;if (l == r) return l;if (lz[x]) pushdown(x);int mid = l + r >> 1;if (L <= mid) {int res = query(ls(x),l,mid,L,R,val);if (res != -1) return res;}if (R > mid) return query(rs(x),mid + 1,r,L,R,val);return -1;
}
int n,a[N],k,d,b[N];
signed main(){cin >> n >> k >> d;for (int i = 1;i <= n;i ++) scanf("%lld",&a[i]);if (d == 0) {int pre = 1;int ansl = 1,ansr = 1;for (int i = 1;i <= n;i ++) {for (;a[i] == a[pre];i ++);if (ansr - ansl + 1 < i - pre) ansl = pre,ansr = i - 1;pre = i;i --;}if (a[n] == a[pre] && n - pre + 1 > ansr - ansl + 1) ansl = pre,ansr = n;cout << ansl << ' ' << ansr << '\n';return 0;}int best_len = 0, best_l = 0;for (int i = 1;i <= n;) {int j = i;int rem = ((a[i] % d) + d) % d;while (j <= n && ((a[j] % d + d) % d) == rem) j ++;int m = j - i;for (int p = 1;p <= m;p ++) {b[p] = (a[i + p - 1] - rem) / d;if (b[p] * d + rem != a[i + p - 1]) {if (a[i + p - 1] < 0) b[p]--;else b[p] ++;}}build(1,1,m);vector<pair<int,int>> max_stk, min_stk;unordered_map<int,int> last_pos;int T = 0;for (int r = 1;r <= m;r ++) {if (last_pos.count(b[r])) T = max(T, last_pos[b[r]]);last_pos[b[r]] = r;while (!max_stk.empty() && max_stk.back().second <= b[r]) {int idx = max_stk.back().first,val = max_stk.back().second;max_stk.pop_back();int prev_idx = max_stk.empty() ? 0 : max_stk.back().first;update(1,1,m,prev_idx + 1,idx,b[r] - val);}max_stk.emplace_back(r, b[r]);while (!min_stk.empty() && min_stk.back().second >= b[r]) {int idx = min_stk.back().first,val = min_stk.back().second;min_stk.pop_back();int prev_idx = min_stk.empty() ? 0 : min_stk.back().first;update(1,1,m,prev_idx + 1,idx,val - b[r]);}min_stk.emplace_back(r, b[r]);int L = query(1,1,m,T + 1,r,k + r);if (L != -1) {int cur_len = r - L + 1;if (cur_len > best_len) best_len = cur_len,best_l = i + L - 1;else if (cur_len == best_len && (i + L - 1) < best_l) best_l = i + L - 1;}}i = j;}cout << best_l << " " << best_l + best_len - 1 << endl;return 0;
}
/*
17 4 0
1 1 4 5 1 4 4 4 2 2 4 4 2 2 2 2 26 1 2
4 3 2 8 6 2*/

相关新闻

  • vue3踩坑:静态dom无法初始化渲染 - 父组件props与侦听器的交互
  • Mysql DBA学习笔记(客户端常用工具) - 教程
  • MATLAB 中 dsp.FFT 系统对象:从原理到实践的完整指南

最新新闻

  • 武汉买猫买狗去哪看?梦宠山庄实地体验分享 - 园友3800037
  • 从零到一:Jetlinks物联网平台服务器部署实战与避坑指南
  • (转)一次ANSYS EM 2023R1 “Request name electronics_desktop does not exist in the licensing pool.“的离谱解决记录
  • 面试被问“你的缺点是什么”,90%的应届生都答错了!(附满分话术)
  • Spring Cloud Alibaba 最佳实践:基于 Spring Boot 4.0 的完整微服务示例项目
  • 三步掌握AI斗地主:如何用DouZero智能助手提升你的游戏胜率

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号