hdu4348 To the moon (segment tree may be persistent)

Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=4348

Title effect: a sequence containing a given number n, the following four operations

1.C lrd: representation of the interval [l, r] plus the number d, and time plus 1

2.Q lr: querying the current time interval [l, r], and

3.H lrt: interrogation time interval t [l, r], and

4.B t: time back to t

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
2 4
0 0
C 1 1 1
C 2 2 -1
Q 1 2
H 1 2 1
Sample Output
4
55
9
15

0
1

 

Problem-solving ideas: You can not mark the lazy pass at the interval when seeking and using segment tree, because under every great pass, then space will be consumed, is likely to burst memory, we can directly when asked, the current range of laziness when labeled with a pass on the parameters, and then find the required section, directly to the accumulated marker from top to bottom laziness and multiplying this interval plus the length of the original interval and it.

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
struct node{
    int l,r;
    ll lazy,sum;
}tree[maxn*30];
int n,m,t,cnt,root[maxn];
void pushup(int rt,int l,int r){
    tree[rt].sum=tree[tree[rt].l].sum+tree[tree[rt].r].sum+tree[rt].lazy*(r-l+1);
}
void build(int &rt,int l,int r){
    rt=++cnt;
    tree[rt].lazy=0;
    if(l==r){
        scanf("%lld",&tree[rt].sum);
        return;
    }
    int mid=(l+r)/2;
    build(tree[rt].l,l,mid);
    build(tree[rt].r,mid+1,r);
    pushup(rt,l,r);
}
void update(int &now,int pre,int L,int R,int val,int l,int r){
    now=++cnt,tree[now]=tree[pre];
    if(L<=l&&R>=r){
        tree[now].sum+=1ll*(r-l+1)*val;
        tree[now].lazy+=val;
        return;
    }
    int mid=(l+r)/2;
    if(L<=mid) update(tree[now].l,tree[pre].l,L,R,val,l,mid);
    if(R>mid) update(tree[now].r,tree[pre].r,L,R,val,mid+1,r);
    pushup(now,l,r);
}
ll query(int now,int L,int R,int lazy,int l,int r){
    if(L<=l&&R>=r){
        return tree[now].sum+1ll*(r-l+1)*lazy;
    }
    int mid=(l+r)/2; ll res=0;
    lazy+=tree[now].lazy;
    if(mid>=L) res+=query(tree[now].l,L,R,lazy,l,mid);
    if(mid<R) res+=query(tree[now].r,L,R,lazy,mid+1,r);
    return res;
}
int main(){
    char op[10];
    scanf("%d%d",&n,&m);
    build(root[0],1,n);
    int l,r,val,T;
    t=0;
    while(m--){
        scanf("%s",op);
        if(op[0]=='C'){
            scanf("%d%d%d",&l,&r,&val);
            t++;
            update(root[t],root[t-1],l,r,val,1,n);
        }else if(op[0]=='Q'){
            scanf("%d%d",&l,&r);
            printf("%lld\n",query(root[t],l,r,0,1,n));
        }else if(op[0]=='H'){
            scanf("%d%d%d",&l,&r,&T);
            printf("%lld\n",query(root[T],l,r,0,1,n));
        }else if(op[0]=='B'){
            scanf("%d",&t);
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zjl192628928/p/11230113.html