线段树模板(区间和+区间最大值 + LAZY标记)
来源:互联网 发布:逆光源网络剧第2集 编辑:程序博客网 时间:2024/05/19 12:38
线段树模板
1. 区间和模板(线段树单点更新)
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define maxn 50005using namespace std;//线段树模板struct node{ int l, r; int sum; //根据情况sum的类型改为ll 或者 ull int mid(){ return (l + r)>>1; }};node tree[maxn*4];int value[maxn];char key[10];int idx, v;int cnt;void init_tree(int root, int l, int r){ tree[root].l = l; tree[root].r = r; if(l == r){ tree[root].sum = value[l]; return ; } init_tree(root<<1, l, (l + r)/2); init_tree(root<<1|1, (l + r)/2 + 1, r); tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;}int query_tree(int root, int l, int r){ if(l<=tree[root].l&&r>=tree[root].r) return tree[root].sum; int mid=tree[root].mid(),ret=0; if(l<=mid) ret+=query_tree(root<<1,l,r); if(r>mid) ret+=query_tree(root<<1|1,l,r); return ret;}void update_tree(int root, int idx, int v){ if(tree[root].l == tree[root].r){ tree[root].sum = v; return; } if(idx <= tree[root].mid()) update_tree(root<<1, idx, v); else update_tree(root<<1|1, idx, v); tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;}
2.最大值模板
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 200005;int n, m;struct node{ int l, r; int MAX_VALUE; //表示区间最大值 int mid(){ return (l + r) >> 1; }};node tree[maxn * 4];int value[maxn];void init(int root, int l, int r){ tree[root].l = l; tree[root].r = r; if(l == r){ tree[root].MAX_VALUE = value[l]; return; } int m = (l + r) >> 1; init(root<<1, l, m); init(root<<1|1, m+1, r); tree[root].MAX_VALUE = max(tree[root<<1].MAX_VALUE, tree[root<<1|1].MAX_VALUE);}void update(int root, int idx, int v){ if(tree[root].l == tree[root].r){ tree[root].MAX_VALUE = v; return; } if(idx <= tree[root].mid()) update(root<<1, idx, v); else update(root<<1|1, idx, v); tree[root].MAX_VALUE = max(tree[root<<1].MAX_VALUE, tree[root<<1|1].MAX_VALUE);}int query(int root, int l, int r){ if(l == tree[root].l && r == tree[root].r) return tree[root].MAX_VALUE; int m = tree[root].mid(); if(l > m) return query(root<<1|1, l, r); else if(r <= m) return query(root<<1, l, r); else return max(query(root<<1, l, m), query(root<<1|1, m+1, r));}
3.LAZY标记模板(线段树区间更新)
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 100010;struct node{ int l, r; ll sum; int mid(){ return (l + r)>>1; }};node tree[maxn*4];ll value[maxn];ll visit[maxn*4]; //懒惰标记void pushDown(int root, int len){ //向下计算并更新线段树节点的之和 if(visit[root]){ visit[root<<1] += visit[root]; visit[root<<1|1] += visit[root]; tree[root<<1].sum += visit[root]*(len - (len>>1)); tree[root<<1|1].sum += visit[root]*(len>>1); visit[root] = 0; //每次更新完根节点需要还原 }}void pushUp(int root){ //向上计算节点之和(根节点 = 左子树值 + 右子树值) tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;}void init(int root, int l, int r){ tree[root].l = l; tree[root].r = r; if(l == r){ tree[root].sum = value[l]; return; } int m = (l + r) >> 1; init(root<<1, l, m); init(root<<1|1, m + 1, r); // 等价于pushUp(root); //tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; pushUp(root);}void update(int root, int op, int ed, int val){ //从[op, ed]区间 if(op == tree[root].l && ed == tree[root].r){ visit[root] += val; tree[root].sum += (ll)((ed - op + 1) * val); return; } if(tree[root].l == tree[root].r){ return; } int m = tree[root].mid(); pushDown(root, tree[root].r - tree[root].l + 1); if(op > m) update(root<<1|1, op, ed, val); else if(ed <= m)update(root<<1, op, ed, val); else{ update(root<<1, op, m, val); update(root<<1|1, m+1, ed, val); } //tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; pushUp(root);}ll query(int root, int l, int r){ if(tree[root].l == l && tree[root].r == r){ return tree[root].sum; } pushDown(root, tree[root].r - tree[root].l + 1); //向下更新节点值 int m = tree[root].mid(); if(l > m) return query(root<<1|1, l, r); else if(r <= m) return query(root<<1, l, r); else return query(root<<1, l, m) + query(root<<1|1, m + 1, r);}
阅读全文
1 0
- 线段树模板(区间和+区间最大值 + LAZY标记)
- 线段树学习笔记(单点更新+区间查询最大值+lazy标记+pushdown操作+区间更新+求区间和)
- 线段树求区间最大值+区间更新+区间求和+lazy标记
- 线段树区间更新模板(lazy延迟标记)(1698)
- 线段树区间修改 lazy标记 大法
- 线段树区间修改 懒惰标记 维护和、最大值、最小值
- 线段树区间和最大值
- 线段树模板(区间和最大值最下值)
- 区间更新 区间和查询 带有延迟标记 线段树 hdu1698; 附:csa 区间加值,维护最大值
- hdu-4587-线段树的区间操作- lazy标记
- SKYLINE uva+线段树+区间的修改+lazy标记
- hdu 1698 线段树区间更新入门(lazy标记)
- 专题 线段树 E(区间更新,使用lazy标记)
- 区间修改lazy线段树
- spojGSS1 线段树维护区间和最大值
- 线段树区间修改之双标记 【lazy两重标记并且分类讨论】
- 郁闷的出纳员 (splay的区间标记模板,删除区间,add标记,类似线段树)
- 线段树区间最大值查询,单点更新,建立模板
- FetchType与FetchMode的区别
- Nginx 主要应用场景
- 笔记19 | 利用MediaRecorder实现录像
- Cloud中Hystrix仪表盘与Turbine集群监控
- 论文笔记-Synthetic Data for Text Localisation in Natural Images
- 线段树模板(区间和+区间最大值 + LAZY标记)
- 如何使用MySQL索引?
- Web开发者易犯的五大严重错误
- LeetCode650. 2 Keys Keyboard
- 怎么批量的将CAD文件转为pdf格式?
- 2017首届全球金融科技与区块链中国峰会—聆听行业领袖的真知灼见
- 当技术为组织所累时怎么办?将你的组织架构旋转90度!
- python 实现线性链表(单链表)--增加合并链表算法
- R与字符串操作