线段树
2015-12-10 00:01
274 查看
线段树对于Laxy还是消化了一晚上,才想明白,之前想错了,只希望能学到点,积累点。
query代表查询,build代表建树,updata代表更新,push_down就是laxy,应该是精华的地方吧。
头
对于线段树求最大值和最小值,要主要返回时的值,下面标注出来了
求和,要注意不需要的地方返回0
最后是更新区间,Laxy操作的地方
主函数
希望没有错误,可能还是理解的不透彻,说不明白,做不来。。。
query代表查询,build代表建树,updata代表更新,push_down就是laxy,应该是精华的地方吧。
头
#include<cstdio> #include<iostream> #include<vector> //包括max函数 using namespace std; int tree[20]; int num[10] = {0, 1, 3, 2, 5, 4, 8}; int add[20]; int n=1;
对于线段树求最大值和最小值,要主要返回时的值,下面标注出来了
int build(int L,int R,int rx) //求最大值 { if( L == R) return tree[rx]=num[L]; return tree[rx]=max(build( L, (L + R )/2,rx*2),build( (L + R)/2+1, R ,rx*2+1 )); } int query(int l, int r,int L,int R,int rx) { if( l > R || r < L) return -0x7ffffff; //如果不在这个区间,就要返回最小的,确保得到最大的 if( l <= L && r >=R) return tree[rx]; return max(query( l , r, L ,(L + R)/2,rx*2) ,query( l, r , ( L +R)/2+1, R,rx*2+1)); }
求和,要注意不需要的地方返回0
int build(int L,int R,int rx) //求和的最大值 { if( L == R) return tree[rx]=num[L]; return tree[rx]=sum(build( L, (L+R)/2,rx*2),build( (L+R)/2+1,R,rx*2+1)); } int query( int l, int r,int L,int R,int rx) { if( l > R || r < L) return 0; //求和不在区间就返回0 if( l <= L && r>= R ) return tree[rx]; return tree[rx]=sum(query(l,r,L,(L+R)/2,rx*2),query(l,r,(L+R)/2+1,R,rx*2+1)); }
最后是更新区间,Laxy操作的地方
int build(int L,int R,int rx) //下面是区间的更新 { if( L == R) return tree[rx]=num[L]; return tree[rx]=sum(build( L, (L+R)/2,rx*2),build( (L+R)/2+1,R,rx*2+1)); } int updata(int l,int r,int L,int R,int rx) //更新 { if ( l > R || r < L) return tree[rx]; if ( l <= L && r >=R ) add[rx]=n*(R-L+1); return tree[rx] += add[rx]; //这个地方找到了应该就去更行它的子节点,但是没有,这就是Laxy操作,直接返回 //到用的时候在去更新,看 push_down函数 } return tree[rx]=sum(updata(l,r,L,(L+R)/2,rx*2),updata(l,r,(L+R)/2+1,R,rx*2+1)); } void push_down(int rx,int L,int R) //Laxy操作 { if( L == R) return ; //如果是叶子节点,无左右孩子所以直接返回 add[rx*2] += ((L+R)/2-L+1)*n; //更新左右的子节点 tree[rx*2] += add[rx*2]; add[rx*2+1] += ( R- (L+R)/2-1+1) *n; tree[rx*2+1] += add[rx*2+1]; } int query( int l, int r,int L,int R,int rx) //查询函数 { if( l > R || r < L) return 0; if( add[rx] != 0) //如果查找的这个区间包括应该更新而未更新的节点,就要去调用push_down 让其更新 { push_down(rx,L,R); add[rx]=0; } if( l <= L && r>= R ) return tree[rx]; return sum(query(l,r,L,(L+R)/2,rx*2),query(l,r,(L+R)/2+1,R,rx*2+1)); }
主函数
int main() { build(1,6,1); updata(2,5,1,6,1); for( int i = 0 ; i < 20; i ++ ) printf("%d ",tree[i]); putchar('\n'); printf("%d" ,query(2,3,1,6,1)); return 0; }
希望没有错误,可能还是理解的不透彻,说不明白,做不来。。。
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例