线段树模板
2013-06-01 16:42
141 查看
摘抄自http://www.notonlysuccess.com/index.php/segment-tree-complete/
maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍
lson和rson分辨表示结点的左儿子和右儿子,由于每次传参数的时候都固定是这几个变量,所以可以用预定于比较方便的表示
以前的写法是另外开两个个数组记录每个结点所表示的区间,其实这个区间不必保存,一边算一边传下去就行,只需要写函数的时候多两个参数,结合lson和rson的预定义可以很方便
PushUP(int rt)是把当前结点的信息更新到父结点
PushDown(int rt)是把当前结点的信息更新给儿子结点
rt表示当前子树的根(root),也就是当前所在的结点
maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍
lson和rson分辨表示结点的左儿子和右儿子,由于每次传参数的时候都固定是这几个变量,所以可以用预定于比较方便的表示
以前的写法是另外开两个个数组记录每个结点所表示的区间,其实这个区间不必保存,一边算一边传下去就行,只需要写函数的时候多两个参数,结合lson和rson的预定义可以很方便
PushUP(int rt)是把当前结点的信息更新到父结点
PushDown(int rt)是把当前结点的信息更新给儿子结点
rt表示当前子树的根(root),也就是当前所在的结点
#define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int maxn = 55555; int lsum[maxn<<2] , rsum[maxn<<2] , msum[maxn<<2]; int cover[maxn<<2]; void PushDown(int rt,int m) { if (cover[rt] != -1) { cover[rt<<1] = cover[rt<<1|1] = cover[rt]; msum[rt<<1] = lsum[rt<<1] = rsum[rt<<1] = cover[rt] ? 0 : m - (m >> 1); msum[rt<<1|1] = lsum[rt<<1|1] = rsum[rt<<1|1] = cover[rt] ? 0 : (m >> 1); cover[rt] = -1; } } void PushUp(int rt,int m) { lsum[rt] = lsum[rt<<1]; rsum[rt] = rsum[rt<<1|1]; if (lsum[rt] == m - (m >> 1)) lsum[rt] += lsum[rt<<1|1]; if (rsum[rt] == (m >> 1)) rsum[rt] += rsum[rt<<1]; msum[rt] = max(lsum[rt<<1|1] + rsum[rt<<1] , max(msum[rt<<1] , msum[rt<<1|1])); } void build(int l,int r,int rt) { msum[rt] = lsum[rt] = rsum[rt] = r - l + 1; cover[rt] = -1; if (l == r) return ; int m = (l + r) >> 1; build(lson); build(rson); } void update(int L,int R,int c,int l,int r,int rt) { if (L <= l && r <= R) { msum[rt] = lsum[rt] = rsum[rt] = c ? 0 : r - l + 1; cover[rt] = c; 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 , r - l + 1); } int query(int w,int l,int r,int rt) { if (l == r) return l; PushDown(rt , r - l + 1); int m = (l + r) >> 1; if (msum[rt<<1] >= w) return query(w , lson); else if (rsum[rt<<1] + lsum[rt<<1|1] >= w) return m - rsum[rt<<1] + 1; return query(w , rson); }
相关文章推荐
- hdu 1166 敌兵布阵 (线段树、树状数组模板,单点更新)
- 线段树模板
- POJ 3667 Hotel(线段树 区间合并 模板题)
- poj 3468 A Simple Problem with Integers 线段树模板区间更新
- 线段树模板
- -----线段树模板
- 线段树模板
- HDU 1823 Luck and Love (二维线段树模板)
- 线段树模板
- 线段树模板(求最大最小)
- hdoj Stars 1541 (树状数组模板&&线段树)
- [dfs序][线段树][模板]hdu5692 Snacks
- 线段树模板及解释
- P3372 【模板】线段树 1 洛谷
- HDU 1754 I Hate it (线段树最大值模板)
- Just a Hook HDU - 1698(线段树区间更换,区间询问模板)
- 线段树模板及其详细解释
- 线段树模板
- 线段树--模板
- ACM常用模板——数据结构——线段树