zoukankan      html  css  js  c++  java
  • 线段树1

    #include<cstdio>
    
    using namespace std;
    
    const int maxn=1e5;
    
    typedef long long int ll;
    
    ll a[maxn];
    
    struct node{
        int v;
        int l,r;
        int tag;
        node *ls,*rs;
        
        inline bool maketag(const ll w){
            v+=(r-l+1)*w;
            tag+=w;
        }
        
        inline void pushup(){
            v=ls->v+rs->v;
        }
        inline void pushdown(){
            if(tag==0)
            return;
            ls->maketag(tag);
            rs->maketag(tag);
            tag=0;
        }
        
      build(const int L,const int R){
        l=L;
        r=R;
        if(l==r){
            tag=0;
            v=a[l];
            ls=rs=NULL;
        }else{
            tag=0;
            int M=(l+r)>>1;
            ls=new node (l,M);
            rs=new node (M+1,r);
            pushup();
        }
        
    }
        
        inline bool inrange(const int L,const int R){
            return (l<=L)&&(r<=R);
        }
        
        inline bool outrange(const int L,const int R){
            return (l>R)||(r<L);
        }
        
        void upd(const int L,const int R,const ll w){
            if(inrange(L,R)){
                maketag(tag);
            }else if(!outrange(L,R)){
                pushdown();
                ls->upd(L,R,w);
                rs->upd(L,R,w);
                pushup();
            }
        }
        
        ll qry(const int L,const int R){
            if(inrange(L,R))
            return v;
            if(outofrange(L,R))
            return 0;
            pushdown();
            return ls->qry(L,R)+rs->qry(L,R);
            
        }
        
    };
    
    int main()
    {
        scanf("%d%d",&n,&q);
        
        for(int i=1;i<=n;i++)
        scanf("%lld",a+i);
        
        node *rot=new node(1,n);
        
        for(ll o,x,y,z;q;q--)
        {
            scanf("%lld%lld%lld",&o,&x,&y);
            
            if(o==1)
            {
                scanf("%lld",&z);
                rot->upd(x,y,z);
            }else{
                printf("%lld
    ",rot->qry(x,y));
            }
        }    
        
        return 0;
        
    }

     阿这。。。。感觉空荡荡的那我就加点解释吧。。。pushup和pushdown是对父子节点之间关系进行的操作,子节点更新父节点时需要用递归来实现,maketag涉及到一个巧妙地修改子节点的技巧,即在提供单点修改操作的线段树中,将父节点打上一个标记,表示其子节点的值需要被修改,在下一次访问到子节点的时候,再去改变子节点的值。inline bool inrange。。。。感性理解吧,没啥好说的。upd是单点修改用的函数。

    build用来建立一个树,把新的点创建为叶节点。qry为区间求和的函数。

  • 相关阅读:
    mysql数据库 及 常用 SQL语句
    移动前端—图片压缩上传实践
    使用Nodejs 的http-proxy 模块做代理服务器的尝试
    Ajax请求参数为文件类型
    <iframe>框架标签的使用
    vue2 核心概念
    关于Web前端密码加密是否有意义的总结
    原生js 与 jQuery对比
    word文档操作
    js (ECMAScript) 对数据处理的 方法、属性总结
  • 原文地址:https://www.cnblogs.com/dairuizhe/p/13246283.html
Copyright © 2011-2022 走看看