题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4348
一开始把lazy标记给push_down了,后来发现这样会让持久化变乱,然后想到不用push_down也可以统计和,改写之后就过了。
#include<bits/stdc++.h> using namespace std; const int maxn=100005; int a[maxn]; int rt[maxn]; int ts; int n; struct Node { int lson,rson; long long val,lz; }node[30*maxn]; int tot; void push_up(int i) { node[i].val=node[node[i].lson].val+node[node[i].rson].val; } //void push_down(int i) //{ // if (node[i].lz==0) return; // int ls=node[i].lson; // int rs=node[i].rson; // node[ls].lz+=node[i].lz; // node[rs].lz+=node[i].lz; // node[ls].val+=node[i].lz*node[ls].len; // node[rs].val+=node[i].lz*node[rs].len; // node[i].lz=0; //} int build(int l,int r) { int th=++tot; node[th].lz=0; if (l==r) node[th].val=a[l]; else { int mid=(l+r)/2; node[th].lson=build(l,mid); node[th].rson=build(mid+1,r); push_up(th); } return th; } int rebuild(int l,int r,int x,int i,int nowl,int nowr) { int th=++tot; node[th].val=node[i].val; node[th].lson=node[i].lson; node[th].rson=node[i].rson; node[th].lz=node[i].lz; if (l==nowl&&r==nowr) { node[th].lz+=x; node[th].val+=x*(nowr-nowl+1); } else { int mid=(nowl+nowr)/2; if (r<=mid) node[th].lson=rebuild(l,r,x,node[i].lson,nowl,mid); else if (l>mid) node[th].rson=rebuild(l,r,x,node[i].rson,mid+1,nowr); else { node[th].lson=rebuild(l,mid,x,node[i].lson,nowl,mid); node[th].rson=rebuild(mid+1,r,x,node[i].rson,mid+1,nowr); } push_up(th); node[th].val+=node[th].lz*(nowr-nowl+1); } return th; } void insert(int l,int r,int x) { rt[++ts]=rebuild(l,r,x,rt[ts-1],1,n); } long long querysum(int l,int r,int i,int nowl,int nowr) { if (nowl==l&&nowr==r) return node[i].val; int mid=(nowl+nowr)/2; // push_down(i); long long res=0; if (l>=nowl&&r<=nowr) res+=node[i].lz*(r-l+1); else if (l<nowl&&r>=nowl&&r<=nowr) res+=node[i].lz*(r-nowl+1); else if (r>nowr&&l>=nowl&&l<=nowr) res+=node[i].lz*(nowr-l+1); else if (l<nowl&&r>nowr) res+=node[i].lz*(nowr-nowl+1); if (r<=mid) res+=querysum(l,r,node[i].lson,nowl,mid); else if (l>mid) res+=querysum(l,r,node[i].rson,mid+1,nowr); else res+=querysum(l,mid,node[i].lson,nowl,mid)+querysum(mid+1,r,node[i].rson,mid+1,nowr); return res; } long long query(int l,int r,int t) { return querysum(l,r,rt[t],1,n); } int main() { int m; while (~scanf("%d%d",&n,&m)) { for (int i=1;i<=n;i++) scanf("%d",&a[i]); ts=tot=0; rt[0]=build(1,n); while (m--) { char s[5]; scanf("%s",s); if (s[0]=='C') { int l,r,d; scanf("%d%d%d",&l,&r,&d); insert(l,r,d); } else if (s[0]=='Q') { int l,r; scanf("%d%d",&l,&r); printf("%I64d ",query(l,r,ts)); } else if (s[0]=='H') { int l,r,t; scanf("%d%d%d",&l,&r,&t); printf("%I64d ",query(l,r,t)); } else { int t; scanf("%d",&t); ts=t; } } } return 0; }