线段树模板(单点更新,区间更新,RMQ)
1.单点更新
说明
单点更新,区间求和(你问我单点求和??你就不会把区间长度设为0啊?)
• sum[]为线段树,需要开辟四倍的元素数量的空间。
• build()为建树操作
• update()为更新操作
• query()为查询操作
时间复杂度:O(nlogn)
使用方法
- build(1, n); 建立一个叶子节点为n个的线段树
- update(pos, val, 1, n); 更新树中下标为pos的叶子节点值增加val
- query(l, r, 1, n); 查询[l ,r]区间值之和
Tips
• 请注意update的目的是增减还是替换,根据情况修改update函数和pushup函数
• 建出来的树为空树,默认每个点值都为0,需要自行将值update上去,或者修改build中sum[rt]=0;为输入操作scanf(“%d”,sum+rt);
模版
// 有注释版
const int maxn=2005+5;
#define lson l,m,rt<<1 //预定子左树
#define rson m+1,r,rt<<1|1 //预定右子树
int sum[maxn<<2];//表示节点,需要开到最大区间的四倍
void pushup(int rt){
//对于编号为rt的节点,他的左右节点分别为rt<<1和rt<<1|1
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
//造树
void build(int l,int r,int rt=1){
//建树操作,生成一个区间为l~r的完全二叉树
//如果到底,则线段长度为0,表示一个点,输入该点的值
if (l==r) {
sum[rt]=0;
return;
}
//准备子树
int m=(l+r)>>1;
//对当前节点建立子树
build(lson);
build(rson);
//由底向上求和
pushup(rt);
}
//更新点和包含点的枝
void update(int pos,int val,int l,int r,int rt=1){
//pos为更新的位置 val为增加的值,正则加,负则减
//l r为区间的两个端点值
//触底,为一个点的时候,该节点值更新
if (l==r) {
sum[rt]+=val;
return;
}
int m = ( l + r ) >> 1;
if (pos<=m) //pos在左子树的情况下,对左子树进行递归
update(pos, val, lson);
else //pos在右子树的情况下,对右子树进行递归
update(pos, val, rson);
//更新包含该点的一系列区间的值
pushup(rt);
}
//查询点或区间
int query(int L,int R,int l,int r,int rt=1){
// L~R为被查询子区间 l~r为“当前”树的全区间
if (L<=l&&r<=R) //子区间包含“当前”树全区间
return sum[rt]; //返回该节点包含的值
int m=(l+r)>>1;
int res=0;
if (L<=m) //左端点在左子树内
res+=query(L, R, lson);
if (R>m) //右端点在右子树内
res+=query(L, R, rson);
return res;
}
2.区间更新
说明
区间更新,区间求和(你问我单点求和??你就不会把区间长度设为0啊?)
• sum[]为线段树,需要开辟四倍的元素数量的空间。
• build()为建树操作
• update()为更新操作
• query()为查询操作
时间复杂度:O(nlogn)
使用方法
- build(1, n); 建立一个叶子节点为n个的线段树
- update(l, r, val, 1, n); 更新线段树中[l, r]区间每个值都增加val
- query(l, r, 1, n); 查询[l ,r]区间值之和
Tips
• 请注意update的目的是增减还是替换,根据情况修改update函数和pushup函数
• 建出来的树为空树,默认每个点值都为0,需要自行将值update上去,或者修改build中sum[rt]=0;为输入操作scanf(“%d”,sum+rt);
模版
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 100005;
int add[maxn<<2],sum[maxn<<2];
void PushUp(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt,int m)
{
if (add[rt])
{
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
sum[rt<<1] += add[rt] * (m - (m >> 1));
sum[rt<<1|1] += add[rt] * (m >> 1);
add[rt] = 0;
}
}
void build(int l,int r,int rt=1)
{
add[rt] = 0;
if (l == r)
{
sum[rt]=0;
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt=1)
{
if (L <= l && r <= R)
{
add[rt] += c;
sum[rt] += c * (r - l + 1);
return ;
}
PushDown(rt , r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(L , R , c , lson);
if (m < R) update(L , R , c , rson);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt=1)
{
if (L <= l && r <= R)
{
return sum[rt];
}
PushDown(rt , r - l + 1);
int m = (l + r) >> 1;
int ret = 0;
if (L <= m) ret += query(L , R , lson);
if (m < R) ret += query(L , R , rson);
return ret;
}
3.RMQ
说明
RMQ:Range Minimum(Maximum) Query
• sum[]为线段树,需要开辟四倍的元素数量的空间。
• build()为建树操作
• update()为更新操作
• query()为查询操作
使用方法
- 根据情况修改RMQ的宏定义
- build(1, n); 建立一个叶子节点为n个的线段树
- update(pos, val, 1, n); 修改树中下标为pos的叶子节点值为val
- query(l, r, 1, n); 查询[l ,r]区间中的RMQ
Tips
• 建出来的树为空树,默认每个点值都为0,需要自行将值update上去,或者修改build中sum[rt]=0;为输入操作scanf(“%d”,sum+rt);
• RMQ为宏定义,请根据情况自行修改为max或者min,对应修改query中的res为-INF或者INF
const int maxn=2005+5;
#define RMQ max
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[maxn<<2]={};
void pushup(int rt){
sum[rt]=RMQ(sum[rt<<1],sum[rt<<1|1]);
}
void build(int l,int r,int rt=1){
if (l==r){
sum[rt]=0;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int pos,int val,int l,int r,int rt=1){
if (l==r) {
sum[rt]=val;
return;
}
int m=(l+r)>>1;
if (pos<=m) update(pos, val, lson);
else update(pos, val, rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt=1){
if (L<=l&&r<=R) return sum[rt];
int m=(l+r)>>1;
int res=-INF; //防负数的坑
if (L<=m) res=RMQ(res,query(L, R, lson));
if (R>m) res=RMQ(res,query(L, R, rson));
return res;
}
线段树模板(单点更新,区间更新,RMQ)的更多相关文章
- HDU 4348.To the moon SPOJ - TTM To the moon -可持久化线段树(带修改在线区间更新(增减)、区间求和、查询历史版本、回退到历史版本、延时标记不下放(空间优化))
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- POJ - 3264 线段树模板题 询问区间最大最小值
这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值. 这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点 ...
- hdu 1754 线段树(单点替换 区间最值)
Sample Input5 61 2 3 4 5Q 1 5 //1-5结点的最大值U 3 6 //将点3的数值换成6Q 3 4Q 4 5U 2 9Q 1 5 Sample Output5659 # i ...
- hdu 1166 线段树(单点增减 区间求和)
Sample Input1101 2 3 4 5 6 7 8 9 10Query 1 3Add 3 6Query 2 7Sub 10 2Add 6 3Query 3 10End Sample Outp ...
- poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...
- 线段树-sum/max/min/区间更新
写一个板子. #include <cstdio> #include <algorithm> using namespace std; +; #define ROOT 1, 1, ...
- 洛谷3372线段树模板题 对区间+k或者查询区间和
#include<bits/stdc++.h> using namespace std; typedef unsigned int ui; typedef long long ll; ty ...
- HDU 1754 I Hate It(线段树之单点更新 区间最值查询)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 140120 ...
- HDUOJ---1754 I Hate It (线段树之单点更新查区间最大值)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
随机推荐
- bzoj1000~1025
以后还是这样 25道题一起发 看着爽 noip失利之后发粪涂墙 刷了一波bzoj 题解: bzoj1000 A+B问题 这题不同的人有不同的写法,我写了个线段树套Treap,应该还是挺简单的 但是看别 ...
- 【LeetCode】066. Plus One
题目: Given a non-negative integer represented as a non-empty array of digits, plus one to the integer ...
- ASP.NET AJAX(Atlas)和Anthem.NET——管中窥豹般小小比较
Anthem.NET近日有朋友和我提到Anthem.NET这个同样基于ASP.NET的Ajax框架,今天有机会亲自尝试了一下.初步的感觉似乎和ASP.NET AJAX不相上下,甚至某些地方要强于ASP ...
- 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)
传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...
- BZOJ2548:[CTSC2002]灭鼠行动
我对模拟的理解:https://www.cnblogs.com/AKMer/p/9064018.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem ...
- python中http的一些编码转换
http的数据需要2种编码解码. 1. url中的特殊字符转换, 比如",', :,//等 python3中通过urllib.parse.quote(..)和urllib.parse.unq ...
- Asp.net工作流workflow实战之书签(二)
1.winform(web程序)下使用工作流 怎样才能像控制台那样让winform或web页面窗体阻塞等待工作流的继续执行呢 2.BookMark书签 书签:和一般的书签看书的时候方便查看上次看的内容 ...
- mina中的发送延时
由于项目需要,用到了 mina 框架进行 tcp 通讯.我是初次接触 mina,于是从 Hello world 开始学习了 mina .期间遇到了一个奇怪的发送数据的延迟问题,解决的过程是曲折的,但找 ...
- (Python编程)Pickle对象
Programming Python, 3rd Edition 翻译 最新版本见:http://wiki.woodpecker.org.cn/moin/PP3eD 19.4. Pickled Obje ...
- PullToRefresh------ListView的使用
第一步 :写出布局文件的设置 <com.handmark.pulltorefresh.library.PullToRefreshListView android:id="@+id/pu ...