模板笔记 ST表 区间选数k

本题链接:用户登录

题目:

样例:

输入
5 3
1 1 2 2 3
1 2
3 3
1 5

输出
4 6

思路:

.        根据题意,给出数组,以及多个区间,问这些区间中,最小值之和 和 最大值之和,分别是多少。

        由于题目中的数组元素是静态性的,典型的 RMQ 问题,给出元素,以及区间,进行询问即可。当然这里也是可以 使用 线段树进行求解,由于这道题是静态性的,所以我们可以直接使用 ST 表 的数据结构,进行求解即可。

线段树 的方式 是 可以解决动态性的 ,也可以解决静态性的,即线段树可以 边修改元素边询问。

ST 表 的方式 是 对口静态性的, 即 只能询问,不可以修改。

        根据这题,我们 “对症下药” 使用 ST表 方式方便些。

       

        ST 表 ,是 典型的 RMQ 数据结构,采用的是 倍增 思想。

        倍增,顾名思义,就是以2幂的成倍的增长。

        其中的核心思想就是:

        通过记录每一个区间的前半段和后半段,

        达到省略询问 重叠的区间,随后返回这些区间的最值

        ST 表类似 动态规划 dp ,根据 倍增关系得到的公式 i + 2^{^{j}} - 1

        我们假设得到一个区间 中的左端点 l  = i  , 那么 根据 倍增 ,我们右端点   r = i + 2^{^{j}} - 1

        这里  r = i + 2^{^{j}} - 1  中  -1 是维护闭区间。

        

        随后,求这个区间的最值,我们可以截取 前半段 和 后半段的最值记录好对应的区间的最值

 随后当求到我们整个  i 到 i + 2^{^{j}} - 1 的最值的时候

我们 取个 max 或者 min (st(i,i + 2^{^{j - 1}} - 1)  , st(i,i + 2^{^{j - 1}},i + 2^{^{j}} - 1))即可。

这样省略的整个区间的求法,解决重叠部分的求最值。

我们假设 求的区间长度 为 K,则 K = R - L + 1,其中 2的次幂作为我们的截半端点的时候一定是

2^{^{r}} <= K    &&      2^{^{r}} > K / 2  ,所以它们两个不部分有一个极限点重叠,所以我们取max和min两个部分的相应最值,相当于求 区间(L,R) 的最值。

由上图,根据  2^{^{r}} = len(截半长度,右端点) 所以我们取右端点的值就是 r =  log_{2}{len}   。

所以我们要对右端点预处理即可得到各个右端点。

模板函数如下:

const int N = 2e5 + 10;
int v[N],n,q;
int stmin[N][22],stmax[N][22];
inline void Init()
{for(int i = 1;i <= n;++i) stmin[i][0] = stmax[i][0] = v[i];for(int j = 1;j <= log2(n);++j){for(int i = 1;i + (1 << j) - 1 <= n;++i){int r = i + (1 << j - 1);stmin[i][j] = min(stmin[i][j - 1],stmin[r][j - 1]);stmax[i][j] = max(stmax[i][j - 1],stmax[r][j - 1]);}}
}
inline int rmq_min(int L,int R)
{int k = log2(R - L + 1);int len = (1 << k);int r = R - len + 1;return min(stmin[L][k],stmin[r][k]);
}
inline int rmq_max(int L,int R)
{int k = log2(R - L + 1);int len = (1 << k);int r = R - len + 1;return max(stmax[L][k],stmax[r][k]);
}

代码详解如下:

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cmath>
#define endl '\n'
#include <unordered_map>
#define int long long
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#define All(x) x.begin(),x.end()
#pragma GCC optimize(3,"Ofast","inline")
#define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e5 + 10;// 这是个二维数组 可以理解为 int[][]  其中这个二维数组存储的是 对应的 R  和   r
// 其中 一维 int[] 存储的是 原端点 R      二维 int[][] 存储的是 截半右端点 r 至于为何 r 开 22 ,
// 这个是由于我们 是 log 以 2 为底、长度为基的数值 得到的右端点,所以我们开存在于我们范围内即可
int st_min[N][22],st_max[N][22];
int v[N]; // 存储原数组元素
int n,q;inline void Init()
{// 预处理求出当前点的 右端点 Rfor(int i = 1;i <= n;++i){// 这里是 当 左右端点相同的时候 它们的最值等于它们本身// 即 : L == R 没有截半,截半端点r = 0st_min[i][0] = st_max[i][0] = v[i];}// 开始求每个截半区间的最值for(int R = 1;R <= log2(n);++R) // 这是区间右端点 R{// 截半区间前提是 截半的右端点 r 区间长度 不超过我们整个数组的区间长度for(int L = 1;L + (1 << R) - 1 <= n;++L){int r = L + (1 << R - 1); // 截半右端点的 r// DP 递推公式   截半区间向右扩展对应的最值,// 当前的区间右端点 R 最值  =  (max or min) [之前的截半最值(L, R - 1 ), 现在截半最值(r ,len - 1)]// 这样一步一步的递推下去,覆盖重叠部分的区间,记录好对应的截半区间的最值st_max[L][R] = max(st_max[L][R - 1],st_max[r][R - 1]); st_min[L][R] = min(st_min[L][R - 1],st_min[r][R - 1]); }}
}inline int rmq_max(int L,int R)
{int k = log2(R - L + 1); // 取出对应的截半区间的原右端点int len = (1 << k);	//截半区间长度int r = R - len + 1; // 取出对应的截半右端点 r// 返回这两个截半区间的最值, 等于我们所求的 L ,R 的最值return  max(st_max[L][k],st_max[r][k]); 
}inline int rmq_min(int L,int R)
{int k = log2(R - L + 1); // 取出对应的截半区间的原右端点int len = (1 << k);	//截半区间长度int r = R - len + 1; // 取出对应的截半右端点 r// 返回这两个截半区间的最值, 等于我们所求的 L ,R 的最值return  min(st_min[L][k],st_min[r][k]); 
}inline void solve()
{cin >> n >> q;for(int i = 1;i <= n;++i) cin >> v[i];Init(); // 开始预处理 ST表 初始化// 存储答案int minsum = 0;int maxsum = 0;while(q--){int l,r;cin >> l >> r;// 询问累加最值minsum += rmq_min(l,r);maxsum += rmq_max(l,r);}cout << minsum << ' ' << maxsum << endl;
}signed main()
{
//	freopen("a.txt", "r", stdin);IOS;int _t = 1;
//	cin >> _t;while (_t--){solve();}return 0;
}

最后提交:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/659057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

A ConvNet for the 2020s

前言 论文名称&#xff1a;A ConvNet for the 2020s  发表时间&#xff1a;CVPR2022  code链接&#xff1a; 代码  作者及组织&#xff1a; Zhuang Liu&#xff0c;Hanzi Mao来自Meta和UC Berkeley。 一句话总结&#xff1a;仿照swin-T思想&#xff0c;重新设计ResNet结构&a…

spark-cannot resolve overloaded method

使用split方法&#xff0c;出现错误&#xff1a;cannot resolve overloaded method 解决方法:那个regex应该是自动生成&#xff0c;所以split括号中输入空引号即可。 入门学习人的愚笨&#xff0c;也要继续坚持&#xff0c;加油&#xff01;

解决npm安装phantomjs失败

失败信息 Progress: resolved 102, reused 102, downloaded 0, added 0, done .pnpm/phantomjs2.1.7/node_modules/phantomjs: Running install script, failed in 21.3s .../node_modules/phantomjs install$ node install.js │ PhantomJS not found on PATH │ Downloading…

消息中间件之RocketMQ源码分析(三)

RocketMQ中的Consumer启动流程 RocketMQ客户端中有两个独立的消费者实现类分别为DefaultMQPullConsumer和DefaultMQPushConsumer&#xff0c; DefaultMQPullConsumer DefaultMQPullConsumer,该消费者使用时需要用户主动从Broker中Pull消息和消费消息&#xff0c;提交消费位点…

vue-router 实现页面路由

vue-router介绍 vue 的官方路由组件 功能包括 嵌套路由映射动态路由选择模块化、基于组件的路由配置路由参数、查询、通配符HTML5 的 history 模式 和 hash 模式 vue-router使用 结合 tabs 组件&#xff0c;实现页面路由 安装 vant-ui 实现底部导航栏 Tabbar-CSDN博客 重点…

图的学习

图的基本概念和术语 图的定义&#xff1a;图是由顶点的有穷非空集合和顶点之间的边的集合组成的&#xff0c;G表示&#xff0c;V是图G中顶点的集合&#xff0c;E是图G中边的集合 无向图&#xff1a;任意两点的边都是无向边组成的图&#xff08;无向边&#xff1a;&#xff08…

R高级绘图 | P1 | 带边缘分布散点图 | 代码注释 + 结果解读

新系列 —— R高级绘图&#xff0c;准备整理所有曾经绘制过的图图和未来需要的图图们的代码&#xff01;预计这个系列会囊括所有常见图形&#xff0c;只提供高级绘图代码&#xff0c;基础绘图主要在 R语言绘图 系列中进行介绍&#xff0c;这个系列咱们主打&#xff1a;需要XX图…

【Web前端实操21】商城官网_白色导航

今日份实现白色导航栏部分&#xff0c;也就是第三部分&#xff0c;效果如图中划线所示&#xff1a; 本次实现代码如之前的全局样式不再赘述&#xff0c;如有需要可以去我博客的Web前端实操19或者20自行查看。 本次主要更新mi.css和index.htm。 实现导航栏所需要的CSS样…

2015年苏州大学837复试机试C/C++

2015年苏州大学复试机试 第一题 题目 有36块砖&#xff0c;现在有36个人&#xff0c;男人能搬4块&#xff0c;女人能搬3块&#xff0c;小孩子两人搬一块&#xff0c;求一次搬完这些砖要男人&#xff0c;女人&#xff0c;小孩多少人&#xff1f; 代码 #include <iostrea…

仰暮计划|“那时候在生产队下面,集体干活,吃大锅饭,由队里分粮食,吃不饱饭是常事,队里分的粮食就那么点,想要吃饱真的太难了”

希望未来的中国越来越好&#xff0c;大家的生活也越来越好 老人是1955年在河南省洛阳市洛宁县的一个小山村里出生的&#xff0c;前半辈子为了生活&#xff0c;为了孩子而打拼&#xff0c;虽然经历了不少的苦难&#xff0c;但后半辈子也算是苦尽甘来&#xff0c;生活美满。现在就…

《Is dataset condensation a silver bullet for healthcare data sharing?》

一篇数据浓缩在医疗数据集应用中的论文。 其实就是在医疗数据集上使用了data condensation的方法&#xff0c;这里使用了DM的方式&#xff0c;并且新增了浓缩时候使用不同的网络。 1. 方法 数据浓缩DC的目的是&#xff1a; E x ∼ P D [ L ( φ θ O ( x ) , y ) ] ≃ E x ∼…

【Vue3+Vite】Vue3视图渲染技术 快速学习 第二期

文章目录 一、模版语法1.1 插值表达式和文本渲染1.1.1 插值表达式 语法1.1.2 文本渲染 语法 1.2 Attribute属性渲染1.3 事件的绑定 二、响应式基础2.1 响应式需求案例2.2 响应式实现关键字ref2.3 响应式实现关键字reactive2.4 扩展响应式关键字toRefs 和 toRef 三、条件和列表渲…

考研高数(共轭根式)

1.定义 共轭根式&#xff1a;是指两个不等于零的根式A、B&#xff0c;若它们的积AB不含根式&#xff0c;则称A、B互为共轭根式。 共轭根式的一个显著特点是通过相乘能把根号去掉&#xff0c;这是很有帮助的 2.常用的共轭根式 3.例题 1&#xff09;求极限 2&#xff09;证明…

常见分类网络的结构

VGG16 图片来自这里 MobilenetV3 small和large版本参数,图片来着这里 Resnet 图片来自这里

【Deep Dive: AI Webinar】数据合作和开源人工智能

【深入探讨人工智能】网络研讨系列总共有 17 个视频。我们按照视频内容&#xff0c;大致上分成了 3 个大类&#xff1a; 1. 人工智能的开放、风险与挑战&#xff08;4 篇&#xff09; 2. 人工智能的治理&#xff08;总共 12 篇&#xff09;&#xff0c;其中分成了几个子类&…

02、全文检索 ------ Solr(企业级的开源的搜索引擎) 的下载、安装、Solr的Web图形界面介绍

目录 Solr 的下载和安装Solr的优势&#xff1a;Lucene与Solr 安装 Solr1、下载解压2、添加环境变量3、启动 Solr Solr 所支持的子命令&#xff1a;Solr 的 Core 和 Collection 介绍Solr 的Web控制台DashBoard&#xff08;仪表盘&#xff09;Logging&#xff08;日志&#xff09…

代码随想录算法训练营29期|day34 任务以及具体任务

第八章 贪心算法 part03 1005.K次取反后最大化的数组和 class Solution {public int largestSumAfterKNegations(int[] nums, int K) {// 将数组按照绝对值大小从大到小排序&#xff0c;注意要按照绝对值的大小nums IntStream.of(nums).boxed().sorted((o1, o2) -> Math.ab…

华为1.24秋招笔试题

华为1.24秋招笔试题 1.题目1 题目详情 - 2024.1.24-华为秋招笔试-第一题-计算积分 - CodeFun2000 1.1题解 import java.util.Scanner;class Main{public static void main(String[] args){Scanner scnew Scanner(System.in);String ssc.next();char[] chs.toCharArray();in…

qt语言国际化(翻译),并实现多窗口同时翻译

一、.pro文件中添加支持的语言 在.pro文件中添加下面几句&#xff0c;支持中文和英文 TRANSLATIONS lanague_cn.ts\lanague_en.ts二、通过qt语言家更新翻译生成.ts文件 完成以后在工程目录可以看到.ts文件 三、通过linguist翻译文件 打开文件 将两个文件同时选中&#xf…

【WPF.NET开发】优化性能:图形呈现层

本文内容 图形硬件呈现层定义其他资源 呈现层为运行 WPF 应用程序的设备定义图形硬件功能和性能级别。 1、图形硬件 对呈现层级别影响最大的图形硬件功能包括&#xff1a; 视频 RAM - 图形硬件中的视频内存量决定了可用于合成图形的缓冲区大小和数量。 像素着色器 - 像素着…