1 条题解
-
1Root (sky1231) LV 8 MOD @ 2020-12-01 11:23:37
#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <deque> using namespace std; namespace dts { typedef long long ll; class segtree{ public: ll size=0; class st_rec{ public: ll rt,rtl,rtr; }; deque<st_rec> rec; deque<ll> fa,lc,rc,sl,sr,smid,sum,sumlz; void reszcl(ll sz) { size=0; rec.resize(sz); fa.clear(),lc.clear(),rc.clear(); sl.clear(),sr.clear(),smid.clear(); sum.clear(),sumlz.clear(); } void set_st(ll ver,ll l,ll r) { rec[ver].rt=-1,rec[ver].rtl=l,rec[ver].rtr=r; } ll len(ll now) { return sr[now]-sl[now]+1; } void update(ll &now,ll last,ll fath,ll ver,ll l,ll r,ll val) { if (now==-1||now+1>size) { now=size++; fa.push_back(fath),lc.push_back(-1),rc.push_back(-1); if (last!=-1) { sl.push_back(sl[last]),sr.push_back(sr[last]),smid.push_back(smid[last]); sum.push_back(sum[last]),sumlz.push_back(sumlz[last]); } else { sum.push_back(0),sumlz.push_back(0); if (now==rec[ver].rt) sl.push_back(rec[ver].rtl),sr.push_back(rec[ver].rtr); else if (now==lc[fa[now]]) sl.push_back(sl[fa[now]]),sr.push_back(smid[fa[now]]); else if (now==rc[fa[now]]) sl.push_back(smid[fa[now]]+1),sr.push_back(sr[fa[now]]); smid.push_back((sl[now]+sr[now])>>1); } } if (last!=-1) sum[now]=sum[last],sumlz[now]=sumlz[last]; if (sl[now]==l&&r==sr[now]) { sum[now]+=len(now)*val; sumlz[now]+=val; if (lc[now]==-1&&last!=-1) lc[now]=lc[last]; if (rc[now]==-1&&last!=-1) rc[now]=rc[last]; } else { if (r<=smid[now]) update(lc[now],(last==-1)?-1:lc[last],now,ver,l,r,val); else if (smid[now]+1<=l) update(rc[now],(last==-1)?-1:rc[last],now,ver,l,r,val); else { update(lc[now],(last==-1)?-1:lc[last],now,ver,l,smid[now],val); update(rc[now],(last==-1)?-1:rc[last],now,ver,smid[now]+1,r,val); } if (lc[now]==-1&&last!=-1) lc[now]=lc[last]; if (rc[now]==-1&&last!=-1) rc[now]=rc[last]; sum[now]=((lc[now]!=-1)?sum[lc[now]]:0)+((rc[now]!=-1)?sum[rc[now]]:0)+len(now)*sumlz[now]; } } ll ask(ll now,ll l,ll r,ll sum_lz) { if (now==-1||now+1>size) return 0; if (sl[now]==l&&r==sr[now]) return sum[now]+len(now)*sum_lz; else { if (r<=smid[now]) return ask(lc[now],l,r,sum_lz+sumlz[now]); else if (smid[now]+1<=l) return ask(rc[now],l,r,sum_lz+sumlz[now]); else return ask(lc[now],l,smid[now],sum_lz+sumlz[now])+ask(rc[now],smid[now]+1,r,sum_lz+sumlz[now]); } } }; segtree ltmst; ll n,m; vector<ll> a; void main() { while (~scanf("%lld%lld",&n,&m)) { a.resize(n); for (ll i=0;i<n;i++) scanf("%lld",&a[i]); ltmst.reszcl(1); ltmst.set_st(0,0,n-1); for (ll i=0;i<n;i++) ltmst.update(ltmst.rec[0].rt,-1,-1,0,i,i,a[i]); for (ll i=1,tag=0;i<=m;i++) { char o; for (o='$';o!='C'&&o!='Q'&&o!='H'&&o!='B';o=getchar()) ; if (o=='C') { if ((++tag)+1>ltmst.rec.size()) ltmst.rec.resize(ltmst.rec.size()+1); ltmst.set_st(tag,0,n-1); ll l,r,val; scanf("%lld%lld%lld",&l,&r,&val); ltmst.update(ltmst.rec[tag].rt,ltmst.rec[tag-1].rt,-1,tag,l-1,r-1,val); } else if (o=='Q'||o=='H') { ll l,r,t; scanf("%lld%lld",&l,&r); if (o=='H') scanf("%lld",&t); else t=tag; printf("%lld\n",ltmst.ask(ltmst.rec[t].rt,l-1,r-1,0)); } else if (o=='B') { ll t; scanf("%lld",&t); tag=t; } } } } } int main() { dts::main(); }
- 1