hdu 4348 To the moon

Posted jklover

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 4348 To the moon相关的知识,希望对你有一定的参考价值。

许久没有更博客了...更点最近做的题吧.

hdu 4348 To the moon

  • 此处的主席树还需实现区间加.如果每次都下传 lazy 标记,显然爆炸.
  • 使用标记永久化来处理.更新时一边走一边及时更新,不再向下时在当前节点打一个标记.
  • 询问的时候将从根出发的链上标记全部累加起来计算贡献.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
    int x=0;
    bool pos=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            pos=0;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return pos?x:-x;
}
const int MAXN=1e5+10;
int a[MAXN],rt[MAXN];
struct PreSegTree{
    struct node{
        int ls,rs;
        int f;
        ll sum;
        node()
            {
                ls=rs=0;
                f=0;
                sum=0;
            }
    }tree[MAXN*20];
    int idx,curt;
    void init()
        {
            idx=0;
            curt=0;
        }
    #define root tree[cur]
    #define lson tree[tree[cur].ls]
    #define rson tree[tree[cur].rs]
    inline void pushup(int cur)
        {
            root.sum=lson.sum+rson.sum;
        }
    void BuildTree(int &cur,int l,int r)
        {
            cur=++idx;
            if(l==r)
                {
                    root.sum=a[l];
                    return;
                }
            int mid=(l+r)>>1;
            BuildTree(root.ls,l,mid);
            BuildTree(root.rs,mid+1,r);
            pushup(cur);
        }
    void update(int lst,int &cur,int l,int r,int L,int R,int v)
        {
            cur=++idx;
            root=tree[lst];
            root.sum+=1LL*v*(min(r,R)-max(l,L)+1);
            if(L<=l && r<=R)
                {
                    root.f+=v;
                    return;
                }
            int mid=(l+r)>>1;
            if(L<=mid)
                update(tree[lst].ls,tree[cur].ls,l,mid,L,R,v);
            if(R>mid)
                update(tree[lst].rs,tree[cur].rs,mid+1,r,L,R,v);
        }
    ll query(int cur,int l,int r,int L,int R,int tag)
        {
            if(L<=l && r<=R)
                return root.sum+1LL*(r-l+1)*tag;
            int mid=(l+r)>>1;
            ll ans=0;
            if(L<=mid)
                ans+=query(tree[cur].ls,l,mid,L,R,tag+root.f);
            if(R>mid)
                ans+=query(tree[cur].rs,mid+1,r,L,R,tag+root.f);
            return ans;
        }
}T;
int n,m;
int main()
{
    while(~scanf("%d%d",&n,&m))
        {
            T.init();
            for(int i=1;i<=n;++i)
                a[i]=read();
            T.BuildTree(rt[0],1,n);
            while(m--)
                {
                    char buf[2];
                    scanf("%s",buf);
                    if(buf[0]=='C')
                        {
                            ++T.curt;
                            int L=read(),R=read(),v=read();
                            T.update(rt[T.curt-1],rt[T.curt],1,n,L,R,v);        
                        }       
                    else if(buf[0]=='Q')
                        {
                            int L=read(),R=read();
                            ll ans=T.query(rt[T.curt],1,n,L,R,0);
                            printf("%lld
",ans);
                        }
                    else if(buf[0]=='H')
                        {
                            int L=read(),R=read(),t=read();
                            ll ans=T.query(rt[t],1,n,L,R,0);
                            printf("%lld
",ans);
                        }
                    else
                        {
                            assert(buf[0]=='B');
                            int t=read();
                            T.curt=t;
                            T.idx=rt[t+1];
                        }
                }
        }
    return 0;
}

以上是关于hdu 4348 To the moon的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4348 To the moon

HDU - 4348 To the moon

hdu 4348 To the moon (主席树)

hdu 4348 To the moon

hdu 4348 To the moon (主席树 区间更新)

[HDU4348]To the moon(主席树+标记永久化)