zoukankan      html  css  js  c++  java
  • POJ

    这里有一篇写的很好的博客:

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

    在完成kuangbin线段树专题前面两个比较简单的结点修改后,这道题就是一道很标准的线段树模板使用, 涉及到了区间的修改

    其中主要是updown这个函数的使用,Lazy标记的思想,直接更新区间进行标记而先不对子节点进行处理,如果需要往下更新再将标记下传一层

    完整代码:

    #include<iostream>
    #include<cstdio>
    #define ll long long
    using namespace std;
    const int MAXN = 5e5+1;
    unsigned ll n,m,a[MAXN],ans[MAXN<<2],tag[MAXN<<2];
    inline ll ls(ll x)
    {
        return x<<1;
    }
    inline ll rs(ll x)
    {
        return x<<1|1;
    }
    
    inline void push_up(ll p)
    {
        ans[p]=ans[ls(p)]+ans[rs(p)];
    }
    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(ls(p),l,mid);
        build(rs(p),mid+1,r);
        push_up(p);
    } 
    inline void f(ll p,ll l,ll r,ll k)
    {
        tag[p]=tag[p]+k;
        ans[p]=ans[p]+k*(r-l+1);
    }
    inline void push_down(ll p,ll l,ll r)
    {
        ll mid=(l+r)>>1;
        f(ls(p),l,mid,tag[p]);
        f(rs(p),mid+1,r,tag[p]);
        tag[p]=0;
    }
    inline void update(ll nl,ll nr,ll l,ll r,ll p,ll k)
    {
        if(nl<=l&&r<=nr)
        {
            ans[p]+=k*(r-l+1);
            tag[p]+=k;
            return ;
        }
        push_down(p,l,r);
        ll mid=(l+r)>>1;
        if(nl<=mid)update(nl,nr,l,mid,ls(p),k);
        if(nr>mid) update(nl,nr,mid+1,r,rs(p),k);
        push_up(p);
    }
    ll query(ll q_x,ll q_y,ll l,ll r,ll p)
    {
        ll res=0;
        if(q_x<=l&&r<=q_y)return ans[p];
        ll mid=(l+r)>>1;
        push_down(p,l,r);
        if(q_x<=mid)res+=query(q_x,q_y,l,mid,ls(p));
        if(q_y>mid) res+=query(q_x,q_y,mid+1,r,rs(p));
        return res;
    }
    int main(){
        int T;
        int cnt =0;
        ll a1,b,c,d,e,f;
        cin>>n>>m;//1 
        for(ll i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    
        build(1,1,n);
        string s; 
           for(int i=0;i<m;i++){
               cin>>s; 
            if(s[0]=='Q'){
                   scanf("%lld%lld",&e,&f);
                printf("%lld
    ",query(e,f,1,n,1));
            }else if(s[0]=='C'){
                scanf("%lld%lld%lld",&b,&c,&d);//1 x y k 含义:将区间[x,y]内每个数加上k
                update(b,c,1,n,1,d);
            }    
        } 
    }
  • 相关阅读:
    Linux网络与服务管理
    输入两个数据,如果输入数据之和为5的倍数,那么就算是输了,停止游戏;如果赢了,接着输入数据。
    switch语句
    计算一个三位数的个位,十位,百位之和
    单分支和双分支选择结构程序设计
    register变量
    static变量
    auto变量
    长双精度类型
    双精度类型变量
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11239115.html
Copyright © 2011-2022 走看看