线段树常见套路
2016-02-10 14:15
323 查看
线段树就是一颗二叉树,
在二叉树上建立区间;
所以第一个板子是如何建立一颗树,我喜欢直接建,比较暴力;
宏定义虽然慢,但是很方便;
单节点更新:既将某坐标的值修改为某个值;
最大值查询
最小值查询
查询区间和
要更新区间和,就必须把当前值储存起来,其中可以用黑科技 inline 函数
动态更新区间点
在二叉树上建立区间;
所以第一个板子是如何建立一颗树,我喜欢直接建,比较暴力;
宏定义虽然慢,但是很方便;
#define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1PS:宏实际是调用文本,所以宏定义中的字母变量必须到时候与函数中的调用字母一致,不然会报错
<strong>void Build(int l,int r,int rt) { if(l==r) { scanf("%d",&MAX[rt]); return; } int m=(l+r)>>1; Build(lson); Build(rson); }</strong>
单节点更新:既将某坐标的值修改为某个值;
<strong>void Update(int p,int add,int l,int r,int rt) { if(l==r) { MAX[rt]=add; return; } int mid=(l+r)>>1; if(p<=mid) Update(p,add,lson); else Update(p,add,rson); MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); } </strong>
最大值查询
<strong>void Build(int l,int r,int rt)//*一颗最大值树 { if(l==r) { scanf("%d",&MAX[rt]); return; } int m=(l+r)>>1; Build(lson); Build(rson); MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); } int Query(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r) return MAX[rt]; int m=(l+r)>>1; int ret=0; if(L<=m) ret=max(ret,Query(L,R,lson)); if(R>m) ret=max(ret,Query(L,R,rson)); return ret; }</strong>
最小值查询
<strong>void Build(int l,int r,int rt)//* 一颗最小值树 { if(l==r) { scanf("%d",&MAX[rt]); return; } int m=(l+r)>>1; Build(lson); Build(rson); MAX[rt]=min(MAX[rt<<1],MAX[rt<<1|1]); } int Query(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r) return MAX[rt]; int m=(l+r)>>1; int ret=0; if(L<=m) ret=min(ret,Query(L,R,lson)); if(R>m) ret=min(ret,Query(L,R,rson)); return ret; } </strong>
查询区间和
要更新区间和,就必须把当前值储存起来,其中可以用黑科技 inline 函数
#include <bits/stdc++.h>
using namespace std ;
#define N 500005
#define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1
int sum[N<<2];
inline void PushPlus(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d", &sum[rt]);
return ;
}
int m = ( l + r )>>1;
build(lson);
build(rson);
PushPlus(rt);
}
int search(int L ,int R ,int l , int r , int rt)
{
int ans = 0 ;
if(L<=l&&R>=r)
{
return sum[rt];
}
int m = (l+r)>>1;
if(L<=m) ans += search(L,R,lson);
if(R>m) ans += search(L,R,rson);
return ans ;
}
动态更新区间点
#define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 #define root 1 , N , 1 #define LL long long const int maxn = 111111; LL add[maxn<<2]; LL 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) { add[rt] = 0; if (l == r) { scanf("%lld",&sum[rt]); 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) { if (L <= l && r <= R) { add[rt] += c; sum[rt] += (LL)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); }
相关文章推荐
- bzoj1407【NOI2002】Savage
- android的数据传递
- arm-linu-gcc安装
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
- Hibernate注解
- 顺序表应用4:元素位置互换之逆置算法
- POJ3320尺取法
- bzoj3207
- LeetCode 56. Merge Intervals
- HDU 1251 统计难题 (字符串-Trie树)
- ireport启动问题
- MySql远程连接无法打开解决办法
- Python 16.2 使用MySQL
- HDU 2047 阿牛的EOF牛肉串
- Combination Sum III 题解
- 51nod 1215:数组的宽度 单调栈
- sql查询优化
- IoRegisterFsRegistrationChange routine
- 如何创建一个完整的C语言程序心得
- C/C++,笔试面试,多种方法求100以内的所有素数