码迷,mamicode.com
首页 > 编程语言 > 详细

线段树&树状数组

时间:2019-10-27 16:41:19      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:while   div   amp   完整   update   代码   down   turn   inter   

线段树:

lazy:记录当前区间更新的值,当需要继续查找时,才将lazy下传到左节点和右节点、

 

完整代码:

(结构体实现)

技术图片
#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;
 } 
View Code

 

线段树&树状数组

标签:while   div   amp   完整   update   代码   down   turn   inter   

原文地址:https://www.cnblogs.com/Lemon1234/p/11747859.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!