• 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;
    }

      

  • 相关阅读:
    《最优化导论》-8梯度方法
    《最优化导论》-7一维搜索方法
    《最优化导论》-6集合约束和无约束优化问题基础
    ubuntu set up 3
    ubuntu set up 2
    ubuntu set up 1
    Xavier and Kaiming Initialization
    Network Initialization: Fan-in and Fan-out
    The Softmax function and its derivative
    GNU Screen使用
  • 原文地址:https://www.cnblogs.com/cjjsb/p/7966117.html
Copyright © 2020-2023  润新知