线段树 模板

来源:互联网 发布:php短信轰炸机 编辑:程序博客网 时间:2024/06/03 09:23

对于二叉树来说,2n是左子节点,2n+1是右子节点。

建树复杂度为O(n),更新和查询的复杂度都是O(lgn)。

要注意对一个区间进行更新的时候不需要一直更新到底,可以提高效率,需要的时候往下带就行。

#define maxn 200000struct node{    int l, r, sum;    int mid(){        return (l+r)>>1;    }};node Tree[maxn<<2];int value[maxn+10]; //从 1 开始赋值 //初始化树,根节点是1void init_tree(int root, int l, int r){    Tree[root].l = l;    Tree[root].r = r;    if(l == r)        Tree[root].sum = value[l];    else{        init_tree(root<<1, l, (l+r)>>1);        init_tree((root<<1)+1, ((l+r)>>1) + 1, r);        Tree[root].sum = Tree[root<<1].sum + Tree[(root<<1)+1].sum;    }}//查找和int query_tree(int root, int l, int r){    int m = Tree[root].mid();    if(l == Tree[root].l && r == Tree[root].r)        return Tree[root].sum;    else{        if(l > m)            return query_tree((root<<1)+1, l, r);        else if(r <= m)            return query_tree(root<<1, l, r);        else            return query_tree(root<<1, l, m) + query_tree((root<<1)+1, m+1, r);    }}void update_tree(int root, int idx, int v){    if(Tree[root].l == Tree[root].r)        Tree[root].sum += v;    else{        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;     }}

出处:http://blog.csdn.net/cfarmerreally/article/details/53574139

原创粉丝点击