线段树模板整理

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

线段树

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

#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

 

以下是维护序列的代码:(滋瓷乘法运算)

 1 #include <cstdio>
 2 
 3 typedef long long LL;
 4 
 5 static const int maxm=100005;
 6 
 7 LL A[maxm],pls[maxm<<2],mul[maxm<<2],tr[maxm<<2];
 8 int left[maxm<<2],right[maxm<<2];
 9 int n,m;
10 LL MOD;
11 
12 int build(int id,int l,int r){
13     left[id]=l;right[id]=r;mul[id]=1;
14     if(l==r)return tr[id]=A[l]%MOD,0;
15     int mid=(l+r)>>1;
16     build(id<<1,l,mid);
17     build(id<<1|1,mid+1,r);
18     tr[id]=(tr[id<<1]+tr[id<<1|1])%MOD;
19 }
20 
21 void pushdown(int id){
22     int l=left[id];int r=right[id];int mid=(l+r)>>1;
23     pls[id<<1]=(pls[id<<1]*mul[id]%MOD+pls[id])%MOD;
24     pls[id<<1|1]=(pls[id<<1|1]*mul[id]%MOD+pls[id])%MOD;
25     mul[id<<1]=(mul[id]*mul[id<<1])%MOD;
26     mul[id<<1|1]=(mul[id]*mul[id<<1|1])%MOD;
27     tr[id<<1]=(tr[id<<1]*mul[id]%MOD+pls[id]*(mid-l+1)%MOD)%MOD;
28     tr[id<<1|1]=(tr[id<<1|1]*mul[id]%MOD+pls[id]*(r-mid)%MOD)%MOD;
29     mul[id]=1;pls[id]=0;
30 }
31 
32 void modify(int id,int l,int r,int c,int opt){
33     if(left[id]>=l&&right[id]<=r){
34         if(opt==1){
35             mul[id]=(mul[id]*c)%MOD;
36             pls[id]=(pls[id]*c)%MOD;
37             tr[id]=(tr[id]*c)%MOD;
38         }else if(opt==2){
39             pls[id]=(pls[id]+c)%MOD;
40             tr[id]=(tr[id]+(LL)c*(right[id]-left[id]+1)%MOD)%MOD;
41         }
42         return ;
43     }
44     if(right[id]<l||left[id]>r)return ;
45     pushdown(id);
46     modify(id<<1,l,r,c,opt);
47     modify(id<<1|1,l,r,c,opt);
48     tr[id]=(tr[id<<1]+tr[id<<1|1])%MOD;
49 }
50 
51 LL Query(int id,int l,int r){
52     if(left[id]>=l&&right[id]<=r)return tr[id]%MOD;
53     if(left[id]>r||right[id]<l)return 0;
54     pushdown(id);
55     return (Query(id<<1,l,r)%MOD+Query(id<<1|1,l,r)%MOD)%MOD;
56 }
57 
58 int main(){
59     int opt,l,r,c;
60     scanf("%d%lld",&n,&MOD);
61     for(int i=1;i<=n;i++)scanf("%lld",&A[i]);
62     scanf("%d",&m);
63 
64     build(1,1,n);
65     
66     while(m--){
67         scanf("%d",&opt);
68         if(opt!=3){
69             scanf("%d%d%d",&l,&r,&c);
70             modify(1,l,r,c,opt);
71         }
72         else scanf("%d%d",&l,&r),printf("%lld\n",Query(1,l,r)%MOD);
73     }
74 
75     return 0;
76 }
View Code

 

posted @ 2017-02-11 11:31  Exbilar  阅读(2599)  评论(1编辑  收藏  举报