模板:线段树

文章目录

  • 引言
  • 思想
  • 模板
    • 建树
    • 单点修改 / 查询
    • 区间修改/查询
  • 总结
  • 练习


引言

有一类题目:要求在区间上维护信息,比如带修改区间求和问题。考虑到枚举求和肯定会超时,我们可以通过一些数据结构来维护信息,例如线段树。
它功能强大,支持区间求和,区间求最值、区间修改等一系列操作。

思想

线段树,是一种二叉搜索树(即每个结点最多有两棵子树,通常叫做左右子树)。
它将一段区间划分为若干单位区间,每一个节点都储存着一段区间[L,R]的信息,其中叶子节点L=R。它的大致思想是:将区间[1,n]平均分成2个小区间,再将小区间平均分成2个更小区间…以此类推,直到区间长度变为1无法分成两个更小的区间。通过对这些小区间进行修改、查询,来实现对大区间的修改、查询。
用线段树维护的问题必须满足可以用两个小区间的信息合并成大区间信息,否则是不可能将大问题划分成子问题来解决的。

下图就是一棵[1,10]的线段树的分解过程。(相同颜色的节点在同一层)
可以证明,线段树的最大深度不超过log2n
在这里插入图片描述

模板

整体来说都是在贯彻递归二分分治的思想。注意k结点的两个孩子编号应分别为2k 和 2k+1
注意:关于线段树的数组要开到4n(最差时)!

建树

思想:常见的做法是遍历整棵线段树,设当前遍历到的节点所代表的区间为[l,r],设中点mid=(l+r)/2,则左子树区间[l,mid],右子树的区间为[mid+1,r],注意要递归到线段树的叶节点才结束,并给每一个节点赋值,叶子节点直接赋值,非叶子节点信息由左右子树信息合并而来。

void build(int k,int l,int r){if(l==r){sum[k]=f[l];return;}int mid=(l+r)>>1;build(2*k,l,mid);build(2*k+1,mid+1,r);sum[k]=sum[2*k]+sum[2*k+1];
}

单点修改 / 查询

用树状数组不好吗
思想:如果当前遍历到目标节点,就返回节点信息。如果不是,设查询位置为x,当前结点区间范围为了[l,r],中点为mid,若x≤mid,则x在左子树的区间,递归当前结点的左孩子;否则x在右子树的区间,递归它的右孩子。

int dotquery(int k,int l,int r,int x){if(l==x)return sum[k];int mid=(l+r) /2;int res=0;if(x<=mid)	return dotquery(2*k,l,mid,x);else return dotquery(2*k+1,mid+1,r,x);
} void dotchange(int k,int l,int r,int x,int v){if(l==r){sum[k]+=v;return;}int mid=(l+r) /2;if(x<=mid) dotchange(2*k,l,mid,x,v);else dotchange(2*k+1,mid+1,r,x,v);sum[k]=sum[2*k]+sum[2*k+1];
}

区间修改/查询

区间查询:
设待查询区间为[x,y],如果当前遍历到的区间被查询区间包含,就直接返回节点信息。如果不是,设当前结点区间范围为[l,r]中点为mid,如果x≤mid,则待查询区间与[l,mid]有交集,递归[l,mid];如果y>mid,则待查询区间与[mid+1,r]有交集,递归[mid+1,r],最后将返回的信息合并就是区间[x,y]的答案。
区间修改
延续区间查询的思想,我们可以找出所有信息发生改变的节点,可现在有一核心问题:我们并不能直接在这些节点上修改,若全部修改,复杂度难以承受。所以,区间修改的关键思路是:只修改对查询有用的点。为此,我们引入“懒标记"的概念。
懒标记:若遍历到的节点带有懒标记,则立即修改当前节点的信息,并把标记下放到左右儿子,然而左右子树的信息不变动,只有遍历到左/右节点时才修改其信息

void Add(int k,int l,int r,int v){add[k]+=v;sum[k]+=(ll)(r-l+1)*v;return;
}
void pushdown(int k,int l,int r,int mid){if(add[k]==0) return;Add(2*k,l,mid,add[k]);Add(2*k+1,mid+1,r,add[k]);add[k]=0;
}
void longchange(int k,int l,int r,int x,int y,int v){if(x<=l&&r<=y){Add(k,l,r,v);return;}int mid=(l+r)>>1;pushdown(k,l,r,mid);if(x<=mid) longchange(2*k,l,mid,x,y,v);if(y>=mid+1) longchange(2*k+1,mid+1,r,x,y,v);sum[k]=sum[2*k]+sum[2*k+1];
}
ll longquery(int k,int l,int r,int x,int y){if(x<=l&&r<=y) return sum[k];int mid=(l+r)>>1;pushdown(k,l,r,mid);ll res=0;if(x<=mid) res+=longquery(2*k,l,mid,x,y);if(y>=mid+1) res+=longquery(2*k+1,mid+1,r,x,y);return res;
}

总结

线段树是很常用强大的数据结构,其功能也远不止求最值和加和这么简单,要想真正掌握,还是要背模板 理解其深层的运作机制

练习

洛谷题单传送门

欢迎各位dl点赞评论,谢谢 收听 拜读观看! awa

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

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

相关文章

Docker最全教程——从理论到实战(三)

容器是应用走向云端之后必然的发展趋势&#xff0c;因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。本篇教程持续编写了2个星期左右&#xff0c;只是为了大家更好地了解、理解和消化这个技术&#xff0c;能够搭上这波车。你可以关注我们的公众号“magiccode…

高并发、低延迟之C#玩转CPU高速缓存(附示例)

写在前面好久没有写博客了&#xff0c;一直在不断地探索响应式DDD&#xff0c;又get到了很多新知识&#xff0c;解惑了很多老问题&#xff0c;最近读了Martin Fowler大师一篇非常精彩的博客The LMAX Architecture&#xff0c;里面有一个术语Mechanical Sympathy&#xff0c;姑且…

RMQ问题:与众不同(st表的高端应用)

解析 预处理 用pre[i]表示以i结尾的最长完美序列起始点&#xff0c;用last[i]表示数字i最后出现的位置 那么可以得到递推式&#xff1a; pre[i]max(pre[i-1],last[x[i]]1);也就是说这个pre要么是受前一位一样的限制&#xff0c;要么是受自己的限制 用f[i]表示以i结尾的最长完…

Docker最全教程——从理论到实战(四)

容器是应用走向云端之后必然的发展趋势&#xff0c;因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。本篇教程持续编写了2个星期左右并且一直在完善、补充具体的细节和实践&#xff0c;预计全部完成需要1到2个月的时间。由于编写的过程中极其费时&#xff0c…

动态规划:openjudge 2.6-3532 最大上升子序列和 解题心得

传送门 题目描述 一个数的序列bi&#xff0c;当b1 < b2 < … < bS的时候&#xff0c;我们称这个序列是上升的。对于给定的一个序列(a1, a2, …,aN)&#xff0c;我们可以得到一些上升的子序列(ai1, ai2, …, aiK)&#xff0c;这里1 < i1 < i2 < … < iK…

边缘化搭建 DotNet Core 2.1 自动化发布和部署(下)

写在前面本篇文章是上一篇边缘化搭建 DotNet Core 2.1 自动化发布和部署(上)的后续操作&#xff0c;本文主要讲解如何开启Docker Remote API&#xff0c;开启Remote API后的权限安全问题。配置Jenkins构建项目&#xff0c;并在云服务器上构建成功。废话不多说&#xff0c;我们一…

边缘化搭建DotNet Core 2.1 自动化构建和部署环境(上)

写在前面写这篇文章的缘由是由于笔者的对新兴技术方向有所追求&#xff0c;但个人资产有限&#xff0c;只能容许购买一台阿里云低配1核2G服务器。服务器上搭建了 Centos7 & Docker & Jenkins & ASP.NET Core 2.0 自动化发布和部署 环境后牺牲了大部分性能。造成了一…

.NET Core实战项目之CMS 第六章 入门篇-Vue的快速入门及其使用

写在前面上面文章我给大家介绍了Dapper这个ORM框架的简单使用&#xff0c;大伙会用了嘛&#xff01;本来今天这篇文章是要讲Vue的快速入门的&#xff0c;原因是想在后面的文章中使用Vue进行这个CMS系统的后台管理界面的实现。但是奈何Vue实现的SPA有一定的门槛&#xff0c;不太…

不止代码:ybtoj-棋盘分割(二维区间dp)

题目描述 将一个8*8的棋盘进行如下分割&#xff1a;将原棋盘割下一块矩形棋盘并使剩下部分也是矩形&#xff0c;再将剩下的部分继续如此分割&#xff0c;这样割了n-1次后&#xff0c;连同最后剩下的矩形棋盘共有n块矩形棋盘。 (每次切割都只能沿着棋盘格子的边进行) 原棋盘上…

通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span

前言作为.net程序员&#xff0c;使用过指针&#xff0c;写过不安全代码吗&#xff1f;为什么要使用指针&#xff0c;什么时候需要使用它&#xff1f;如果能很好地回答这两个问题&#xff0c;那么就能很好地理解今天了主题了。C#构建了一个托管世界&#xff0c;在这个世界里&…

AC自动机:例题与机制详解

介绍 AC自动机是kmp算法和trie树的结合 大体就是做这样的题用&#xff1a; 可以发现&#xff0c;这题和trie树的区别是把多个单词往一篇文章匹配&#xff0c;而trie恰好相反 匹配的时候其实就是判断子串&#xff0c;所以又用到了kmp 定义失配指针nxt[i]&#xff1a;表示root到…

.NET Core实战项目之CMS 第七章 设计篇-用户权限极简设计全过程

写在前面这篇我们对用户权限进行极简设计并保留其扩展性。首先很感谢大家的阅读&#xff0c;前面六章我带着大家快速入门了ASP.NET Core、ASP.NET Core的启动过程源码解析及配置文件的加载过程源码解析并引入依赖注入的概念、Git的快速入门、Dapper的快速入门、Vue的快速入门。…

2021“MINIEYE杯”中国大学生算法设计超级联赛(5)Random Walk 2(推式子+矩阵逆+矩阵乘)

Random Walk 2 【2.4】Gauss-Jordan消元法求矩阵的逆 高斯消元求矩阵的逆&#xff0c;伴随单位矩阵一起消元即可。 [A,I]→[I,A−1][\text A,\text I]\to [\text I,\text A^{-1}][A,I]→[I,A−1] 移项变形&#xff0c;后就是个矩阵的逆&#xff0c;为啥赛时不写&#xff1f;&a…

参加胶东开发者技术大会有感

2015年的时候&#xff0c;也是在12月&#xff0c;我和Bob(https://www.cnblogs.com/nianming/)去北京参加了“全球架构师峰会”&#xff0c;在那次会议上&#xff0c;来自百度、腾讯、阿里巴巴、京东、美团、新浪微博、Twitter等公司的架构师、技术专家们分享了各自在架构方面的…

专题:数列信息传递问题转化为图论合点问题(ybtoj-数列询问+序列破解)

文章目录前言&#xff1a;一、数列询问&#xff08;取模&#xff09;解析代码二、序列破解&#xff08;奇偶性&#xff09;解析代码thanks for reading&#xff01;前言&#xff1a; 在一个数列a中&#xff0c;对于一个大区间A和组成它的两个小区间a&#xff0c;b&#xff1b;…

Docker最全教程——从理论到实战(五)

在笔者参加腾讯容器服务技术交流会时&#xff0c;我们了解到了藏区牧民的目前的生活艰辛状况&#xff0c;因此除了在同事朋友之间推荐其土特产之外&#xff0c;我们也在此进行初步分享&#xff0c;希望略尽绵薄之力&#xff0c;能够帮助到他们&#xff1a;货真价实、确保都是37…

2021牛客暑期多校训练营6 J-Defend Your Country(无向图点双+思维)

无向图联通分量 点u是割点&#xff0c;当且仅当 特判树根&#xff1a;u为树根&#xff0c;且u有多于1棵子树u不为树根&#xff0c;在递归树上u存在子节点v&#xff0c;满足&#xff1a;dfnu≤lowv\text{dfn}_u\leq \text{low}_vdfnu​≤lowv​ 如上图&#xff0c;v想走到u的组…

不止代码:循环比赛(分治)

循环比赛日程表&#xff08;match&#xff09; 【问题描述】 解析 dfs或分治 分治可以不断递归4个小正方形 左上右下为前一半&#xff0c;左下右上后一半 dfs就很无脑了 代码 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath…

前瞻科技,引领未来!Microsoft Connect(); 2018即将重磅来袭!

怎么用一句话点燃全球的开发者&#xff1f;——Microsoft Connect(); 2018即将重磅来袭&#xff01;每一个观点都能引发科技狂潮&#xff0c;每一项技术都将提速技术进程&#xff0c;由微软举办的 Microsoft Connect(); 2018 即将在太平洋时间12月4日8:30拉开帷幕&#xff01;大…

P5048-[Ynoi2019 模拟赛]Yuno loves sqrt technology III【分块】

正题 题目链接:https://www.luogu.com.cn/problem/P5048 题目大意 就是这个 【QA】区间众数&#xff0c;但空间很小 长度为nnn的序列&#xff0c;要求支持查找区间众数出现次数。 强制在线 1≤n,m≤51051\leq n,m\leq 5\times 10^51≤n,m≤5105 解题思路 空间小就不能用蒲公…