zoukankan      html  css  js  c++  java
  • Luogu P3372 【模板】线段树 1

      终于再过线段树。

      参考可禾大神的线段树,然后在down的时候把 add[root*2]+=add[root] 打成了 add[root+2]+=add[root]; 调了一个下午,还被嘲讽。

      对于区间修改主要用的是Lazy Tag,把增量延迟下方。

      可以达到O(nlogn)。

      这次代码里有注释。

    #include<cstdio>
    using namespace std;
    typedef long long LL;
    const int N=100005;
    LL seg[N*4+10],add[N*4+10],a[N],n,q,x,y,z,c,i;
    inline void read(LL &x)
    {
        x=0; char ch=getchar(); int flag=1;
        while (ch<'0'||ch>'9') { if (ch=='0') flag=-1; ch=getchar(); }
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        x*=flag;
    }
    inline void write(LL x)
    {
        if (x/10) write(x/10);
        putchar(x%10+'0');
    }
    inline void up(LL root) { seg[root]=seg[root*2]+seg[root*2+1]; } //向上传递信息 
    inline void down(LL root,LL l,LL r) //延迟标记下传 
    {
        if (add[root])
        {
            add[root*2]+=add[root];
            add[root*2+1]+=add[root];
            seg[root*2]+=add[root]*l;
            seg[root*2+1]+=add[root]*r;
            add[root]=0;
        }
    }
    inline void build(LL root,LL l,LL r) //递归建边,注意要向上传递 
    {
        if (l==r) seg[root]=a[l]; else
        {
            LL mid=l+r>>1;
            build(root*2,l,mid);
            build(root*2+1,mid+1,r);
            up(root);
        }
    }
    inline LL query(LL root,LL l,LL r,LL ql,LL qr) //区间求和,标记下传!!! 
    {
        if (l>=ql&&r<=qr) return seg[root];
        else
        {
            LL mid=l+r>>1;
            down(root,mid-l+1,r-mid);
            LL res=0;
            if (ql<=mid) res+=query(root*2,l,mid,ql,qr);
            if (mid<qr) res+=query(root*2+1,mid+1,r,ql,qr);
            return res;
        }
    }
    inline void change(LL root,LL l,LL r,LL ql,LL qr,LL v) //区间修改,线段树的核心,注意修改之后既会影响到它的父节点,也影响到它的儿子 
    {
        if (l>=ql&&r<=qr)
        {
            seg[root]+=(r-l+1)*v;
            add[root]+=v;
        } else 
        {
            LL mid=l+r>>1;
            down(root,mid-l+1,r-mid);
            if (ql<=mid) change(root*2,l,mid,ql,qr,v);
            if (mid<qr) change(root*2+1,mid+1,r,ql,qr,v);
            up(root);
        }
    }
    int main()
    {
        read(n); read(q);
        for (i=1;i<=n;++i)
        read(a[i]);
        build(1,1,n);
        while (q--)
        {
            read(c);
            if (c==1) { read(x); read(y); read(z); change(1,1,n,x,y,z); } else
            { read(x); read(y); write(query(1,1,n,x,y)); putchar('
    '); }
        }
        return 0;
    }

      

  • 相关阅读:
    KMP算法
    字典树从第i个构造HDU2846
    字典树的数组实现 HDU1671
    kruskal算法的套路
    HDU1598最小生成树+贪心处理
    第一次结对编程作业
    第一次个人编程作业
    第一次博客作业
    springBoot启动报 `NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;`问题解决
    redis远程连接 安全模式问题解决
  • 原文地址:https://www.cnblogs.com/cjjsb/p/7966117.html
Copyright © 2011-2022 走看看