【板子】短序列dp(换成维护更小常数维度的dp)
当dp的转移常数空间非常大比如dp[100000][100000]但是dp内维护的值非常小比如1-10我们就可以选择维护dp[100000][10]或dp[10][100000];而值代表另一个维度比如 l r的中间翻倍子序列长度翻倍子序列很小所以可以维护从任意 r 结尾子序列长度为 x 的最小 l 来极大缩小常数。DP 状态的某一维通常是长度很小≤60但每一层的转移涉及在满足某个权值条件的历史状态中找最优值需要用线段树/树状数组加速。一、方法总结核心思想步骤做什么为什么① 发现长度上界​证明/观察到答案枚举长度 ≤ O(logV)可以逐长度枚举不会 TLE② 定义 DP 状态​fi,j​ 以 i 结尾、长度为 j 的某种极值通常是最小起点 / 最大终点把选子序列转化为递推③ 值域限制 → 区间查询​转移条件形如 L≤ak​≤R转化为在离散化权值上的区间查询线段树/树状数组直接上④ 控制下标顺序​正序/倒序枚举 i保证查到的都是前面/后面的状态不用再管下标维线段树只管权值⑤ 离线/半在线回答询问​每算完一层顺手用后缀/前缀最值更新所有询问的答案免去存所有 fi,j​适用场景速判看到以下特征就可以往这个方向想子序列需要满足某种乘法/指数型增长条件2x≤y≤3x、y≥kx、yy×c 等//dp值限制在非常小的范围多次区间询问求最长合法子序列长度转移条件是前面找一个满足条件的位置取某个最值常见变体变体改哪里条件是 y≥2x只有下界rightId设为 m无穷大条件是 y2x 精确相等区间退化为单点查询用数组/map 就行求的是最长长度的具体方案多记一个pre指针回溯询问强制在线把所有 fi,j​ 存下来对每列做 RMQ/线段树长度不是 log 级而是 O(n)失效得换思路单调栈/贪心/决策单调性二、通用板子定义序列 b (b1, b2, . . . , bm) 是合法的当且仅当对于所有 2 ≤ i ≤ m都有2bi−1 ≤ bi ≤ 3bi−1.特别地长度为 1 的序列一定合法。给定一个长度为 n 的正整数序列 a需要回答 q 个区间询问。每次给定区间 [l, r]求 al, al1, . . . , ar 中最长合法子序列的长度。所选元素不要求连续但必须保持相对顺序。1 ≤ n, q ≤ 2 · 10e51 ≤ ai ≤ 10e181 ≤ l ≤ r ≤ n。核心思路1. DP 状态设计设 fi,j​ 表示以第 i 个元素结尾、长度为 j 的合法子序列中最靠左的开头位置即最小的起始下标。当 j1 时fi,1​i单个元素自己就是合法子序列。当 j1 时我们要找一个 ki满足 2ak​≤ai​≤3ak​且 fk,j−1​ 尽可能小这样得到的序列整体更靠右更容易被包含在询问区间里。转移方程fi,j​ki2ak​≤ai​≤3ak​​min​fk,j−1​2. 用线段树加速转移转移有两个限制下标限制ki我们只需从小到大或从大到小枚举 i保证只用到之前的 k。权值限制ak​∈[⌈ai​/3⌉,⌊ai​/2⌋]等价于 ai​∈[2ak​,3ak​]。代码采用了倒序枚举 i从 n 到 1的巧妙方式维护一棵线段树以离散化后的 a 值为下标线段树每个节点存储已经遍历过的元素下标更大的 fk,j−1​ 的最小值。对于当前 i需要找的是后面的某个 kki满足 2ai​≤ak​≤3ai​。这正好对应线段树上区间 [leftIdi​,rightIdi​] 的查询。查询得到的最小值就是 fi,j​代码中记为cur[i]。然后把当前的 fi,j−1​即prev[i]更新进线段树供更前面的 i 使用。这样我们在 O(logm)m 为离散化后数值种类时间内完成了单次转移。3. 如何回答区间询问对于一个询问 [l,r]如果存在某个 i∈[l,r] 使得 fi,j​≥l那就说明能在 [l,r] 内找到一个长度为 j 的合法子序列开头 ≥l结尾 i≤r。代码中使用了一个等价但更易实现的判断计算出cur[i]即 fi,j​后求一个后缀最小值数组suf[i] min_{k \ge i} cur[k]。如果suf[l] r说明存在一个结尾 ≥l 且开头 ≤r 的长度为 j 的序列结合 f 的定义这个序列整体落在 [l,r] 内的条件被满足于是更新答案为 j。由于我们是按长度 j2,3,… 依次计算的并且只要当前长度可行就更新ans[id] len最终每个询问就会留下最大可行长度。核心结构//涉及权值线段树离散化不是最基础的板子仅面向类似题目// // 通用板子逐层DP 权值线段树优化转移 // 解决区间询问最长合法子序列长度 // 时间复杂度O(n log n * max_len) // #include bits/stdc.h using namespace std; const int INF 1e9; const int MAXN 200005; // ---------- 权值线段树区间最小值---------- struct SegMin { int n; vectorint t; SegMin(int m) { n 1; while (n m) n 1; t.assign(2 * n, INF); } void update(int p, int val) { if (val INF) return; int x p n - 1; if (t[x] val) return; t[x] val; for (x 1; x; x 1) t[x] min(t[x1], t[x1|1]); } int query(int l, int r) { if (l r) return INF; int res INF; l n - 1; r n - 1; while (l r) { if (l 1) res min(res, t[l]); if (!(r 1)) res min(res, t[r--]); l 1; r 1; } return res; } }; // ---------- 主逻辑 ---------- void solve(const vectorlong long a, const vectorpairint,int queries) { int n a.size() - 1; // a[1..n] int q queries.size(); // --- Step 1: 离散化 --- vectorlong long vals(a.begin() 1, a.end()); sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); int m vals.size(); auto get_id [](long long x) { return lower_bound(vals.begin(), vals.end(), x) - vals.begin() 1; }; auto get_end [](long long x) { // upper_bound 版本 return upper_bound(vals.begin(), vals.end(), x) - vals.begin(); }; vectorint pos(n 1), L(n 1), R(n 1); for (int i 1; i n; i) { pos[i] get_id(a[i]); L[i] get_id(a[i] * 2); // ← 题目条件2*a[i] ≤ a[k] R[i] get_end(a[i] * 3 - 1); // ← 题目条件a[k] ≤ 3*a[i] } // --- Step 2: 初始化长度为1 --- vectorint prev(n 2); for (int i 1; i n; i) prev[i] i; // --- Step 3: 逐层 DP --- vectorint cur(n 2); vectorint suf(n 2); vectorint ans(q, 1); SegMin seg(m); for (int len 2; ; len) { seg SegMin(m); // 重置 fill(cur.begin(), cur.end(), INF); // 倒序枚举找后面的 k i for (int i n; i 1; --i) { if (L[i] R[i]) cur[i] seg.query(L[i], R[i]); seg.update(pos[i], prev[i]); } // 后缀最小值 int best INF; for (int i n; i 1; --i) { best min(best, cur[i]); suf[i] best; } if (best INF) break; // 这一层已经没有合法序列了 // 更新所有询问 for (int id 0; id q; id) { int l queries[id].first, r queries[id].second; if (suf[l] r) ans[id] len; } prev.swap(cur); } // 输出 for (int x : ans) cout x \n; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin n q; vectorlong long a(n 1); for (int i 1; i n; i) cin a[i]; vectorpairint,int queries(q); for (int i 0; i q; i) cin queries[i].first queries[i].second; solve(a, queries); return 0; }权值线段树SegMinstruct SegMin { int n; vectorint t; SegMin(int m) { n 1; while (n m) n 1; t.assign(2 * n, INF); } void update(int p, int val) { ... } int query(int l, int r) { ... } };普通线段树权值线段树下标含义​数组的位置第几个元素元素的值本身​叶子节点​对应a[i]这个位置的数对应值为x的数有多少个典型用途​区间求和、区间修改、区间最值查排名、查第 k 大、统计某个值范围内有多少个数这是一个维护区间最小值的线段树但它的下标不是数组的位置而是数值离散化后的值。比如原数组里有数字{3, 5, 12, 100}离散化后变成{1, 2, 3, 4}。那线段树下标1~4分别对应这些数。在每个下标里我们存的是已经遍历过的、值为该数的那些元素它们的 DP 值的最小值。两个操作update(p, val)告诉线段树值为p的位置我来报到一个值val你帮我取个 min。query(l, r)问线段树在区间[l, r]也就是值在[l, r]范围内的所有元素里最小的 DP 值是多少为什么用线段树因为我们要快速在一段权值区间里找最小值暴力扫是 O(n) 的线段树是 O(logn)。离散化部分vectorlong long vals(a.begin() 1, a.end()); sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); int m vals.size();原数组 ai​ 的范围是 1∼10e18不能直接当下标用。离散化就是把它们压缩到 1∼mm≤n让线段树开得下。auto get_id [](long long x) { return lower_bound(vals.begin(), vals.end(), x) - vals.begin() 1; };二分查找给我一个数 x告诉我它在离散化数组里的编号从 1 开始方便线段树。pos[i] get_id(a[i]); // a[i] 自己的编号 L[i] get_id(a[i] * 2); // 2*a[i] 的下界编号 R[i] get_end(a[i] * 3 - 1); // 3*a[i] 的上界编号回忆题目要求2ak​≤ai​≤3ak​如果我们正序 DP 找前面的 k。但我们的板子是倒序做的含义反过来找后面的 k满足 2ai​≤ak​≤3ai​。L[i]后面那个数 ak​ 至少要是 2ai​所以在离散化数组里的最小位置。R[i]后面那个数 ak​ 最多是 3ai​所以在离散化数组里的最大位置。也就是说后面所有合法的 k它们的pos[k]一定落在[L[i], R[i]]这个闭区间里。改成别的题时需要动的地方位置改什么L[i] get_id(a[i] * 2)改成下界条件R[i] get_end(a[i] * 3 - 1)改成上界条件seg.query(L[i], R[i])如果要求最大值就换成SegMax相应改min→max、INF→-INFprev[i] i如果 DP 定义变了比如以 i 开头的初始化跟着改suf[l] r判断条件根据你定义的 f 的含义调整

相关新闻

软考高项论文写作全攻略:从理论到实战的45分通关秘籍

软考高项论文写作全攻略:从理论到实战的45分通关秘籍

1. 项目概述:为什么说论文是软考高项的“生死线”?如果你正在备考信息系统项目管理师(俗称“软考高项”),那你一定听过这句话:“得论文者得天下”。这绝不是危言耸听。作为高级资格认证,高项考试…

2026/7/30 3:38:25 阅读更多 →
高速光耦HCPL2630数据手册解读与电路设计实战指南

高速光耦HCPL2630数据手册解读与电路设计实战指南

1. 项目概述:从“芯片恐惧症”到“手册自由”每次拿到一片新的芯片,尤其是像光耦这种看起来“简单”但参数表密密麻麻的器件,你是不是也和我一样,有过瞬间的迷茫?数据手册动辄十几二十页,全英文&#xff0c…

2026/7/30 3:38:25 阅读更多 →
小红书内容管理神器:XHS-Downloader 的完整使用指南

小红书内容管理神器:XHS-Downloader 的完整使用指南

小红书内容管理神器:XHS-Downloader 的完整使用指南 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接&#…

2026/7/30 3:38:25 阅读更多 →

最新新闻

Java集成K3Cloud WebApi实战:认证、会话管理与数据交互详解

Java集成K3Cloud WebApi实战:认证、会话管理与数据交互详解

1. 项目概述:当JAVA遇上K3Cloud如果你是一名企业级应用开发者,尤其是经常需要处理ERP系统集成的朋友,那么“JAVA调用K3Cloud WebApi接口”这个标题,大概率能让你会心一笑,或者眉头一皱。这背后不是什么高深莫测的黑科技…

2026/7/30 3:47:29 阅读更多 →
SpringBoot+Vue新冠物资管理系统架构与优化实践

SpringBoot+Vue新冠物资管理系统架构与优化实践

1. 项目概述:新冠物资管理系统的技术架构与价值这个基于SpringBootVueMySQL的新冠物资管理系统源码,是当前公共卫生应急场景下的典型解决方案。我在去年参与某地级市防疫指挥中心信息化建设时,就采用了类似架构。整套系统采用前后端分离设计&…

2026/7/30 3:47:29 阅读更多 →
RLC元件阻抗特性测定:从理论到实践的频率响应分析

RLC元件阻抗特性测定:从理论到实践的频率响应分析

1. 从“感觉”到“数据”:为什么我们需要测定R、L、C的阻抗特性在电子电路的世界里,电阻(R)、电感(L)和电容(C)是三个最基础、最核心的无源元件。任何一个电路板,从最简单…

2026/7/30 3:47:29 阅读更多 →
Python 基础 一文通关函数:从基础定义、文档规范到高级参数与 Lambda

Python 基础 一文通关函数:从基础定义、文档规范到高级参数与 Lambda

前言在 Python 编程中,函数是代码复用的基石。很多初学者虽然会写 def,但往往忽略了文档规范、作用域陷阱以及高阶参数的使用。本文将结合 Python 函数基础与进阶特性,带你系统性地掌握函数编程的核心知识。第一部分:夯实基础——…

2026/7/30 3:47:29 阅读更多 →
查看Windows当前应用的组策略

查看Windows当前应用的组策略

如果你希望在电脑上查看所有有效的组策略设置,以下是操作方法。 什么是Windows中的组策略 在Windows世界中,组策略为网络管理员提供了一种将特定设置分配给用户组或计算机组的方法。然后,无论何时组中的用户登录到联网的PC,或无论何时启动组中的PC,都会应用这些设置。 …

2026/7/30 3:47:29 阅读更多 →
单相桥式全控整流电路Matlab Simulink仿真建模与深度分析

单相桥式全控整流电路Matlab Simulink仿真建模与深度分析

1. 项目概述:从理论到实践的整流电路仿真在电力电子领域,单相桥式全控整流电路是一个绕不开的经典拓扑。无论是作为教材中的标准案例,还是工业应用中AC-DC变换的基础单元,理解它的工作原理和动态特性都至关重要。然而,…

2026/7/30 3:46:28 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻