zoukankan      html  css  js  c++  java
  • 线段树模板

    线段树模板

    可实现区间加法,区间求和。

    具体看代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define max 1000001
    #define ll long long 
    using namespace std;
    unsigned ll n,m,a[max],ans[max*4],tag[max*4];
    inline void fix(ll p)
    {
        ans[p]=ans[p<<1]+ans[p<<1|1];
        //由于是这个区间统一改变,所以ans数组要加元素个数次啦
        //就是记录当前节点所代表的区间
    }
    void build(ll p,ll l,ll r)
    {
        tag[p]=0;
        if(l==r)
        {
            ans[p]=a[l];
            return ;
        }
        ll mid=(l+r)>>1;
        build(p<<1,l,mid);
        build(p<<1|1,mid+1,r);
        fix(p);
    }
    inline void f(ll p,ll l,ll r,ll k)
    {
        tag[p]+=k;
        ans[p]+=k*(r-l+1);
    }
    inline void pushdown(ll p,ll l,ll r)
    {
        ll mid=(l+r)>>1;
        f(p<<1,l,mid,tag[p]);
        f(p<<1|1,mid+1,r,tag[p]);
        tag[p]=0;
    }
    inline void update(ll nl,ll nr,ll l,ll r,ll p,ll k)//区间加法 
    {
        //nl,nr为要修改的区间
        //l,r,p为当前节点所存储的区间以及节点的编号
        if(nl<=l&&nr>=r)
        {
            ans[p]+=k*(r-l+1);
            tag[p]+=k;
            return ;
        }
        pushdown(p,l,r);
        ll mid=(l+r)>>1;
        if(nl<=mid) update(nl,nr,l,mid,p<<1,k);
        if(nr>mid) update(nl,nr,mid+1,r,p<<1|1,k);
        fix(p);
    }
    ll query(ll nl,ll nr,ll l,ll r,ll p)//区间查询 
    {
        //nl,nr为要修改的区间
        //l,r,p为当前节点所存储的区间以及节点的编号
        ll res=0;
        if(nl<=l&&nr>=r) return ans[p];
        ll mid=(l+r)>>1;
        pushdown(p,l,r);
        if(nl<=mid) res+=query(nl,nr,l,mid,p<<1);
        if(nr>mid) res+=query(nl,nr,mid+1,r,p<<1|1);
        return res;
    }
    int main()
    {
        ll b,c,d,e,f;
        scanf("%lld%lld",&n,&m);
        for(unsigned int i=1;i<=n;i++)
          scanf("%lld",&a[i]);
        build(1,1,n);
        while(m--)
        {
            ll g;
            scanf("%lld",&g);
            switch(g)
            {
                case 1://区间加法 
                {
                    scanf("%lld%lld%lld",&b,&c,&d);
                    update(b,c,1,n,1,d);
                    break;
                }
                case 2://区间求和 
                {
                    scanf("%lld%lld",&e,&f);
                    printf("%lld
    ",query(e,f,1,n,1));
                    break;
                }
            }    
        }
        return 0;
    }

    本文参考https://pks-loving.blog.luogu.org/senior-data-structure-qian-tan-xian-duan-shu-segment-tree

  • 相关阅读:
    关于lucene断点续索引和增量索引的问题
    发布一个关于统计时间段的MDX语句
    【蛙蛙推荐】想设计一个关于软件开发的元搜索引擎,希望大家支持
    python中and和or的用法
    Hadoop实战中高级部分 之 Hadoop MapReduce高级编程
    (转)对实时分析与离线分析的思考(二)
    数据分析站点导航
    MapReduce:详解Shuffle过程
    分析能力的8个等级(My Level)
    (转)Tire Tree
  • 原文地址:https://www.cnblogs.com/mxrmxr/p/9677390.html
Copyright © 2011-2022 走看看