线段树模板(单点更新和区间更新)

/*
   查询时间是O(logN)
   更新时间是O(logN)
   1.单点更新
   2.成段更新
   3.区间合并
*/ 
#include<iostream>
using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=55555;
int sum[maxn<<2]={0};//这个要初始化为0 

//将子节点的数据传到根节点 
void PushUp(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
//递归的创建树,并且更新到根节点,sum保存了这个线段的值 
void build(int l,int r,int rt)
{
    //cout<<l<<" "<<r<<" "<<rt<<endl;
    if(l==r){
        cin>>sum[rt];
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    PushUp(rt);
} 
int query(int left,int right,int l,int r,int rt)
{
    if(l==left&&r==right)
    {
        return sum[rt];
    }
    int mid=(l+r)>>1;
    int ret=0;
    
    if(right<=mid) ret+=query(left,right,l,mid,rt<<1);
    else if(left>=mid+1) ret+=query(left,right,mid+1,r,rt<<1|1);
    else
    {
        ret+=query(left,mid,l,mid,rt<<1);
        ret+=query(mid+1,right,mid+1,r,rt<<1|1);
    }
    return ret;
}
//改变一个节点,并且更新它的父节点的值 
void update(int p,int add,int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]+=add;
        return;
    }
    int m=(l+r)>>1;
    if(p<=m) 
        update(p,add,l,m,rt<<1);
    else
        update(p,add,m+1,r,rt<<1|1);
    //将更新传递到上层节点
    PushUp(rt); 
} 
int main()
{
    //1.
    build(1,10,1);
    cout<<query(1,3,1,10,1)<<endl;
    update(3,6,1,10,1);
    cout<<query(2,7,1,10,1)<<endl;
    update(10,-2,1,10,1);
    update(6,3,1,10,1);
    cout<<query(3,10,1,10,1)<<endl;
    
    system("pause");
    return 0;
}
/*
延迟更新

#include <cstdio>
#include <algorithm>
using namespace std;
 
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 111111;
int h , w , n;
int col[maxn<<2];
int sum[maxn<<2];
void PushUp(int rt) {
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m) {
    if (col[rt]) {
        col[rt<<1] = col[rt<<1|1] = col[rt];
        sum[rt<<1] = (m - (m >> 1)) * col[rt];
        sum[rt<<1|1] = (m >> 1) * col[rt];
        col[rt] = 0;
    }
}
void build(int l,int r,int rt) {
    col[rt] = 0;//这个应该是 
    sum[rt] = 1;
    if (l == r) return ;
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt) {
    if (L <= l && r <= R) {
        col[rt] = c;
        sum[rt] = c * (r - l + 1);
        return ;
    }
    PushDown(rt , r - l + 1);
    int m = (l + r) >> 1;
    if (L <= m) update(L , R , c , lson);
    if (R > m) update(L , R , c , rson);
    PushUp(rt);
}
int main() {
    int T , n , m;
    scanf("%d",&T);
    for (int cas = 1 ; cas <= T ; cas ++) {
        scanf("%d%d",&n,&m);
        build(1 , n , 1);
        while (m --) {
            int a , b , c;
            scanf("%d%d%d",&a,&b,&c);
            update(a , b , c , 1 , n , 1);
        }
        printf("Case %d: The total value of the hook is %d.\n",cas , sum[1]);
    }
    return 0;
} 
*/

你可能感兴趣的:(线段树)