题意:给出一个序列,四种操作
C l r d: Adding a constant d for every {Ai | l <= i <= r}, and increase the timestamp by 1, this is the only operation that will cause the timestamp increase.
Q l r: Querying the current sum of {Ai | l <= i <= r}.
H l r t: Querying a history sum of {Ai | l <= i <= r} in time t.
B t: Back to time t. And once you decide return to a past, you can never be access to a forward edition anymore.
对于操作建树,只有当遇到C时时间戳才上升,时间对应的结点建树,dfs整棵树线段树更新区间得到答案
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma comment(linker, "/STACK:1024000000,1024000000");
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 200005
int n,m;
int fir[maxn],nex[maxn],v[maxn],e_max;
long long sum[4*maxn],tag[4*maxn],ans[maxn];
struct Q
{
char s[3];
int l,r,c,id;
friend bool operator < (Q A,Q B)
{
return A.idq[maxn];
void init_()
{
memset(fir,-1,sizeof fir);
e_max=0;
}
void add_edge(int s,int t)
{
int e=e_max++;
v[e]=t;
nex[e]=fir[s];
fir[s]=e;
}
void init(int l,int r,int k)
{
tag[k]=sum[k]=0;
if(l==r)
{
scanf("%lld",&sum[k]);
return ;
}
int mid=l+r>>1;
init(l,mid,k<<1);
init(mid+1,r,k<<1|1);
sum[k]=sum[k<<1]+sum[k<<1|1];
}
void pushdown(int k,int l,int r)
{
if(!tag[k]) return ;
int mid=l+r>>1;
tag[k<<1]+=tag[k];
sum[k<<1]+=tag[k]*(mid-l+1);
tag[k<<1|1]+=tag[k];
sum[k<<1|1]+=tag[k]*(r-mid);
tag[k]=0;
}
void update(int d,int s,int t,int l,int r,int k)
{
if(s==l&&r==t)
{
sum[k]+=(r-l+1)*(long long)d;
tag[k]+=d;
return ;
}
pushdown(k,l,r);
int mid=l+r>>1;
if(t<=mid) update(d,s,t,l,mid,k<<1);
else if(s>mid) update(d,s,t,mid+1,r,k<<1|1);
else
{
update(d,s,mid,l,mid,k<<1);
update(d,mid+1,t,mid+1,r,k<<1|1);
}
sum[k]=sum[k<<1]+sum[k<<1|1];
}
long long query(int s,int t,int l,int r,int k)
{
if(s==l&&r==t)
{
return sum[k];
}
pushdown(k,l,r);
int mid=l+r>>1;
if(t<=mid) return query(s,t,l,mid,k<<1);
else if(s>mid) return query(s,t,mid+1,r,k<<1|1);
else return query(s,mid,l,mid,k<<1)+query(mid+1,t,mid+1,r,k<<1|1);
}
void dfs(int k)
{
for(int i=fir[k]; ~i; i=nex[i])
{
int e=v[i];
if(q[e].s[0]=='Q')
{
ans[q[e].id]=query(q[e].l,q[e].r,1,n,1);
}
else if(q[e].s[0]=='C')
{
update(q[e].c,q[e].l,q[e].r,1,n,1);
dfs(e);
update(-q[e].c,q[e].l,q[e].r,1,n,1);
}
else if(q[e].s[0]=='H')
{
ans[q[e].id]=query(q[e].l,q[e].r,1,n,1);
}
}
}
int ti[maxn];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init_();
init(1,n,1);
int now=0;
ti[now]=0;
for(int i=1; i<=m; i++)
{
scanf("%s",&q[i].s);
if(q[i].s[0]=='Q')
{
scanf("%d%d",&q[i].l,&q[i].r);
add_edge(ti[now],i);
}
else if(q[i].s[0]=='C')
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].c);
add_edge(ti[now],i);
ti[++now]=i;
}
else if(q[i].s[0]=='H')
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].c);
add_edge(ti[q[i].c],i);
}
else
{
scanf("%d",&q[i].c);
now=q[i].c;
}
q[i].id=i;
}
dfs(0);
for(int i=1; i<=m; i++)
{
if(q[i].s[0]=='H'||q[i].s[0]=='Q')
printf("%lld\n",ans[i]);
}
}
return 0;
}