线段树专题一:基本操作

来源:互联网 发布:淘宝客丢单如何找回 编辑:程序博客网 时间:2024/06/13 00:57
线段树是一种二叉搜索树,它将一个区间划分成n个单元区间,每个单元区间对应线段树中的一个叶结点。使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩。
以维护区间的最值为例:
声明
struct node{    int l, r, up, down;    int mid(){        return (l + r) >> 1;    }}tree[MAX << 2];


建立线段数
void buildtree(int l, int r, int rt){    tree[rt].l = l;    tree[rt].r = r;    if(l == r){        scanf("%d",&tree[rt].up);        tree[rt].down = tree[rt].up;        return;    }    int mid = tree[rt].mid();    buildtree(l, mid, rt << 1);    buildtree(mid + 1, r, rt << 1 | 1);    tree[rt].up = max(tree[rt << 1].up, tree[rt << 1 | 1].up);    tree[rt].down = min(tree[rt << 1].down, tree[rt << 1 | 1].down);}

询问
void query(int l, int r, int rt){    if(tree[rt].l >= l && tree[rt].r <= r){        Max = max(tree[rt].up, Max);        Min = min(tree[rt].down, Min);        return;    }    int mid = tree[rt].mid();    if(r <= mid)    query(l, r, rt << 1);    else if(l > mid)    query(l, r, rt << 1 | 1);    else{        query(l, mid, rt << 1), query(mid + 1, r, rt << 1 | 1);    }}



0 0