当前位置: 首页 > news >正文

UVa 12572 RMQ Overkill

题目描述

给定一个长度为NNN1≤N≤100001 \leq N \leq 100001N10000)的非负整数序列,每个元素的值小于101010。对于所有满足0≤i≤j<N0 \leq i \leq j < N0ij<N的子区间(i,j)(i, j)(i,j),求出该区间的最小值,然后将所有这些最小值求和,最后对100000000710000000071000000007取模输出。

输入包含多组测试用例(不超过120120120组),每组用例第一行是NNN,第二行是一个长度为NNN的数字字符串。

样例分析

样例输入

3 143 3 413 3 121

样例输出

13 11 7

以第一个样例143为例:

  • 子区间(0,0)(0,0)(0,0)最小值111
  • 子区间(0,1)(0,1)(0,1)最小值111
  • 子区间(0,2)(0,2)(0,2)最小值111
  • 子区间(1,1)(1,1)(1,1)最小值444
  • 子区间(1,2)(1,2)(1,2)最小值333
  • 子区间(2,2)(2,2)(2,2)最小值333

总和=1+1+1+4+3+3=13= 1 + 1 + 1 + 4 + 3 + 3 = 13=1+1+1+4+3+3=13

题目分析

直接做法的复杂度

最直接的想法是枚举所有子区间,对每个子区间扫描求最小值。子区间的数量为:

N(N+1)2\frac{N(N+1)}{2}2N(N+1)

N=10000N = 10000N=10000时,子区间数量约为5×1075 \times 10^75×107,对每个区间求最小值又会增加O(N)O(N)O(N)的时间,显然会超时。

核心思路:贡献计数法

我们不能枚举区间,而应该换个角度:枚举每个元素,计算它作为最小值出现在多少个区间中

对于位置iii上的元素a[i]a[i]a[i],如果我们可以知道:

  • 向左最多能延伸到多远,使得a[i]a[i]a[i]仍然是该区间的最小值
  • 向右最多能延伸到多远,使得a[i]a[i]a[i]仍然是该区间的最小值

那么包含iii且以a[i]a[i]a[i]为最小值的子区间数量 = (左侧可延伸长度) × (右侧可延伸长度)。

边界处理技巧(去重)

当数组中有相同元素时,需要小心处理,避免同一个区间的最小值被重复计算。

常用策略

  • 向左找第一个严格小于a[i]a[i]a[i]的元素(遇到相等的就停下)
  • 向右找第一个小于等于a[i]a[i]a[i]的元素(遇到相等的继续)

这样每个子区间的最小值只会被最左边那个最小值元素统计到,保证不重不漏。

图解说明

假设数组为[2, 5, 3, 3, 1],考虑中间的333(下标222):

下标:01234:25331
  • 向左找第一个严格小于333的元素:下标000222,所以左边界是000(实际左侧延伸从111开始)
  • 向右找第一个小于等于333的元素:下标444111,所以右边界是444(实际右侧延伸到333

那么包含下标222且以333为最小值的区间:

  • 左端点可选:1,21, 21,2(共222种)
  • 右端点可选:2,32, 32,3(共222种)
  • 总区间数=2×2=4= 2 \times 2 = 4=2×2=4

验证:(1,2)(1,2)(1,2)(1,3)(1,3)(1,3)(2,2)(2,2)(2,2)(2,3)(2,3)(2,3)最小值都是333

高效算法:单调栈

单调栈可以在O(N)O(N)O(N)时间内找到每个元素左右两侧第一个比它小(或小等于)的元素位置。

算法步骤

  1. 左侧扫描:维护一个单调递增栈(栈底到栈顶递增),找左边第一个严格小于当前元素的位置
  2. 右侧扫描:维护一个单调递增栈,找右边第一个小于等于当前元素的位置
  3. 计算贡献:对每个iii,累加a[i]×(i−left[i])×(right[i]−i)a[i] \times (i - left[i]) \times (right[i] - i)a[i]×(ileft[i])×(right[i]i)
  4. 取模:对109+710^9+7109+7取模

时间复杂度

  • 每个元素入栈出栈各一次,O(N)O(N)O(N)
  • 总复杂度O(N)O(N)O(N),可以轻松应对N=10000N=10000N=10000120120120组数据

完整代码

// RMQ Overkill// UVa ID: 12572// Verdict: Accepted// Submission Date: 2026-05-21// UVa Run Time: 0.010s//// 版权所有(C)2026,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constintMOD=1000000007;intmain(){ios::sync_with_stdio(false);cin.tie(0);intn;string s;while(cin>>n>>s){// 将字符数组转换为整数数组vector<int>a(n);for(inti=0;i<n;++i)a[i]=s[i]-'0';vector<int>left(n),right(n);stack<int>st;// 第一步:找左边第一个严格小于 a[i] 的位置for(inti=0;i<n;++i){while(!st.empty()&&a[st.top()]>=a[i])st.pop();left[i]=st.empty()?-1:st.top();st.push(i);}// 清空栈,准备右侧扫描while(!st.empty())st.pop();// 第二步:找右边第一个小于等于 a[i] 的位置for(inti=n-1;i>=0;--i){while(!st.empty()&&a[st.top()]>a[i])st.pop();right[i]=st.empty()?n:st.top();st.push(i);}// 第三步:累加每个元素作为最小值的贡献longlongans=0;for(inti=0;i<n;++i){longlongcnt=(longlong)(i-left[i])*(right[i]-i);ans=(ans+a[i]*cnt)%MOD;}cout<<ans<<'\n';}return0;}

总结

方法时间复杂度空间复杂度是否可行
暴力枚举O(N3)O(N^3)O(N3)O(1)O(1)O(1)❌ 超时
预处理区间最小值O(N2)O(N^2)O(N2)O(N2)O(N^2)O(N2)❌ 内存超限
单调栈贡献计数O(N)O(N)O(N)O(N)O(N)O(N)✅ 完美通过

本题的核心技巧是“贡献计数”“单调栈”的结合。通过将问题从“枚举所有区间”转化为“统计每个元素作为最小值的次数”,再利用单调栈快速找到左右边界,成功将复杂度降至线性。

这种思维方式在区间最值相关问题中非常常见,例如“直方图最大矩形”“所有子数组最小值之和”等经典题目都使用了类似的思想。

http://www.zskr.cn/news/1341649.html

相关文章:

  • 【编号884】江西省各城市-春节人口迁徙规模数据(2019-2025)
  • UVa 250 Pattern Matching Prelims
  • 嵌入式测试学习第 16 天:复位电路、电源电路基础原理
  • Python微服务架构:从单体到分布式的演进
  • UVa 253 Cube Painting
  • 5大优势解锁跨平台直播聚合:PureLive如何重塑你的直播观看体验
  • 2026年4月超纯水设备企业推荐,10吨双级高纯水设备/高纯水设备/超纯水设备/软化水设备,超纯水设备采购渠道怎么选择 - 品牌推荐师
  • 2026年山地车定制厂家综合:途锐达凭何成为口碑之选? - 2026年企业推荐榜
  • 轻量级状态事件总线 eventbusx-js 开源使用教程
  • C/C++函数调用的几种方式总结
  • 2026会议复印机租赁标杆名录:公司复印机租赁/办公室打印机租赁/单位复印机租赁/单位打印机租赁/品牌复印机租赁/选择指南 - 优质品牌商家
  • 2026企业网盘选型对比:坚果云领衔,5款主流产品优劣与场景建议
  • Rust分布式系统最佳实践:构建高可用、高性能的后端服务
  • 15. tsconfig.json 配置详解
  • 专业级图片去重神器:彻底告别重复照片的数字困扰
  • 14. 声明文件(Declaration Files)
  • 2025-2026年国内北京国际小学推荐:五校口碑好的评测 课后活动避免兴趣培养不足注意事项 - 品牌推荐
  • 吉他初学者音阶怎么弹?吉他音阶怎么练效果最好? - 雨林谷
  • 边缘AI框架:在边缘设备上运行AI模型
  • 3步打造智能字幕系统:MaxSubtitle插件深度解析
  • 2026年5月新消息:成都PE给水管制造厂的技术革新与市场格局分析 - 2026年企业推荐榜
  • 深入解析Token质押:从核心原理到未来布局
  • 2026年4月米线加盟品牌选哪家:小吃加盟什么好、小吃加盟品类推荐、小吃加盟店什么好、小吃加盟推荐什么品牌、小吃店加盟联系方式选择指南 - 优质品牌商家
  • 2026年Q2南充广安区域租赁服务商排行及联系方式:四川鼎全机械租赁有限公司联系电话、南充吊车租赁电话、南充施工垫路铁板租赁选择指南 - 优质品牌商家
  • 【蒙古文语音合成行业突破】:ElevenLabs独家支持U+1800–U+18AF+U+18B0–U+18F5双Unicode区段,附官方未公开的蒙古文预处理脚本
  • 【限时解密】ElevenLabs未开放的客家话语音fine-tuning沙箱环境:如何用不到200条标注语句,在72小时内将模型MOS分从3.1提升至4.4(附私有化微调checklist)
  • 毕业设计 深度学习车道线检测(源码+论文)
  • 手写一个AI代码审查员:Claude Agent SDK + MCP 深度实战
  • cursor-vip:当AI编程工具遇上共享经济,你的代码从此有了智能伙伴
  • 雷达信号体制识别