首页 > 其他 > 详细

线段树模板整理

时间:2017-02-11 12:25:15      阅读:155      评论:0      收藏:0      [点我收藏+]

   线段树算是一种较为简单的中级数据结构了,线段树本身其实还是很简单的,就是一棵二叉树,每一个节点维护一块区间的信息,如果根节点是$[1,n]$,那么左儿子就是$[1,n/2]$,右儿子就是$[n/2+1,n]$,如此二分下去就是一棵线段树了,查找的时间复杂度是$O(log2n)$的,有图为证:(网上找的)

技术分享

下面是某线段树模板题的代码:

技术分享
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long LL;
static const int maxm=1e6+10;
LL tree[maxm],lazy[maxm],A[maxm],left[maxm],right[maxm];
int n,m;

void build(int num,int l,int r){
    left[num]=l;right[num]=r;
    int mid=(l+r)>>1;
    if(l==r){ tree[num]=A[l]; return; }
    build(num<<1,l,mid);
    build(num<<1|1,mid+1,r);
    tree[num]=tree[num<<1]+tree[num<<1|1];
}

void pushdown(int num){
    if(lazy[num]){
        int mid=(left[num]+right[num])>>1;
        tree[num<<1]+=(mid-left[num]+1)*lazy[num];
        tree[num<<1|1]+=(right[num]-mid)*lazy[num];
        lazy[num<<1]+=lazy[num];
        lazy[num<<1|1]+=lazy[num];
        lazy[num]=0;
    }
}

void update(int num,int l,int r,LL add){
    if(left[num]>=l&&right[num]<=r){
        tree[num]+=(right[num]-left[num]+1)*add;
        lazy[num]+=add;
        return;
    }
    if(left[num]>r||right[num]<l)return;
    pushdown(num);
    update(num<<1,l,r,add);
    update(num<<1|1,l,r,add);
    tree[num]=tree[num<<1]+tree[num<<1|1];
}

LL Query(int num,int l,int r){
    if(left[num]>=l&&right[num]<=r)return tree[num];
    if(left[num]>r||right[num]<l) return 0;
    LL ret=0;
    pushdown(num);
    ret+=Query(num<<1,l,r);
    ret+=Query(num<<1|1,l,r);
    return ret;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",&A[i]);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int f,x,y;LL add;
        scanf("%d",&f);
        switch(f){
            case 1:scanf("%d%d%lld",&x,&y,&add);update(1,x,y,add);break;
            case 2:scanf("%d%d",&x,&y);printf("%lld\n",Query(1,x,y));break;
            default:printf("Orz %%%");break;
        }
    }

    return 0;
}
View Code

 

线段树模板整理

原文:http://www.cnblogs.com/Exbilar/p/6388902.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!