线段树&&树状数组

Posted transcendent-heming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树&&树状数组相关的知识,希望对你有一定的参考价值。

#include<iostream>
#include<cstdio>
#define maxn 100005
using namespace std;
struct node{
    int l,r,sum,lazy;
}tree[maxn<<2];
void pushUp(int root){
    tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
}
void pushDown(int root){
    if(tree[root].lazy){
        cout<<"AAA"<<endl;
        tree[root<<1].sum = (tree[root<<1].r - tree[root<<1].l +1)*tree[root].lazy;
        tree[root<<1|1].sum = (tree[root<<1|1].r - tree[root<<1|1].l +1)*tree[root].lazy;
        tree[root<<1].lazy += tree[root].lazy;
        tree[root<<1|1].lazy += tree[root].lazy;
        tree[root].lazy = 0;
    } 
}
void buildTree(int root,int l,int r){
    tree[root].l = l; 
    tree[root].r = r; 
    tree[root].lazy = 0;
    if(l==r){
        scanf("%d",&tree[root].sum);
        return;
    }
    int mid = (l+r)>>1;
    buildTree(root<<1,l,mid);
    buildTree(root<<1|1,mid+1,r);
    pushUp(root);
}
void updatePoint(int root,int id,int v){
    if(tree[root].l==id && tree[root].r==id){
        tree[root].sum += v;
        cout<<"root="<<root<<"  sum="<<tree[root].sum<<endl; 
        return;
    }
    int mid = (tree[root].l + tree[root].r)>>1;
    if(id<=mid){
        updatePoint(root<<1,id,v);
    }else{
        updatePoint(root<<1|1,id,v);
    }
    pushUp(root);
}
void updateInterval(int root,int l,int r,int v){
    if(tree[root].l==l && tree[root].r==r){
        tree[root].sum += (tree[root].r-tree[root].l +1)*v;
        tree[root].lazy += v;
        return;
    }
    pushDown(root);
    int mid = (tree[root].l + tree[root].r)>>1;
    if(r<=mid){
        updateInterval(root<<1,l,mid,v);
    }else if(l>=mid){
        updateInterval(root<<1|1,mid+1,r,v);
    }else{
        updateInterval(root<<1,l,mid,v);
        updateInterval(root<<1|1,mid+1,r,v);
    }
    pushUp(root);
}
int query(int root,int l,int r){
    if(tree[root].l==l && tree[root].r==r){
        return tree[root].sum;
    }
    pushDown(root);
    int mid = (tree[root].l + tree[root].r)>>1;
    if(r<=mid){
        query(root<<1,l,r);
    }else if(l>=mid){
        query(root<<1|1,l,r);
    }else{
        return query(root<<1,l,mid) + query(root<<1|1,mid+1,r);
    }
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    buildTree(1,1,n);
    
    while(m--){
        int op,l,r,v,id,ans;
        scanf("%d",&op);
        if(op==1){
            scanf("%d %d",&id,&v);
            updatePoint(1,id,v);
        }else if(op==2){
            scanf("%d %d %d",&l,&r,&v);
            updateInterval(1,l,r,v);
        }else{
            scanf("%d %d",&l,&r);
            ans = query(1,l,r);
            printf("ans = %d",ans);
        }
    }
    return 0;
 } 

以上是关于线段树&&树状数组的主要内容,如果未能解决你的问题,请参考以下文章

线段树&树状数组

逆序对 线段树&树状数组

非原创codeforces 1070C Cloud Computing 线段树&树状数组

HDU-1166 敌兵布阵 (线段树&&树状数组入门)

学习:树状数组&线段树

Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组