zoukankan      html  css  js  c++  java
  • 线段树模板(单点更新和区间更新)

    /*
       查询时间是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;
    } 
    */
  • 相关阅读:
    线程学习笔记(一)
    进程间通信
    管道通信操作
    在程序中执行shell命令
    进程控制(一)
    Makefile文件学习总结
    进程学习笔记
    C#不安全代码和指针
    Unity3D ShaderLab 修改渲染队列进行深度排序
    Unity3D ShaderLab 透明裁剪着色器
  • 原文地址:https://www.cnblogs.com/zhanglanyun/p/2496711.html
Copyright © 2011-2022 走看看