hdu 4348 To the moon
阿新 • • 發佈:2019-02-16
assert define mes nod truct turn int oid getc
許久沒有更博客了...更點最近做的題吧.
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\n",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\n",ans); } else { assert(buf[0]=='B'); int t=read(); T.curt=t; T.idx=rt[t+1]; } } } return 0; }
hdu 4348 To the moon