[hdu 4348]区间修改区间查询可持久化线段树

时间:2023-08-17 17:21:16

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4348

一开始把lazy标记给push_down了,后来发现这样会让持久化变乱,然后想到不用push_down也可以统计和,改写之后就过了。

#include<bits/stdc++.h>
using namespace std; const int maxn=;
int a[maxn];
int rt[maxn];
int ts;
int n; struct Node
{
int lson,rson;
long long val,lz;
}node[*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=;
if (l==r) node[th].val=a[l];
else
{
int mid=(l+r)/;
node[th].lson=build(l,mid);
node[th].rson=build(mid+,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+);
}
else
{
int mid=(nowl+nowr)/;
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+,nowr);
else
{
node[th].lson=rebuild(l,mid,x,node[i].lson,nowl,mid);
node[th].rson=rebuild(mid+,r,x,node[i].rson,mid+,nowr);
}
push_up(th);
node[th].val+=node[th].lz*(nowr-nowl+);
}
return th;
} void insert(int l,int r,int x)
{
rt[++ts]=rebuild(l,r,x,rt[ts-],,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)/;
// push_down(i);
long long res=;
if (l>=nowl&&r<=nowr) res+=node[i].lz*(r-l+);
else if (l<nowl&&r>=nowl&&r<=nowr) res+=node[i].lz*(r-nowl+);
else if (r>nowr&&l>=nowl&&l<=nowr) res+=node[i].lz*(nowr-l+);
else if (l<nowl&&r>nowr) res+=node[i].lz*(nowr-nowl+);
if (r<=mid) res+=querysum(l,r,node[i].lson,nowl,mid);
else if (l>mid) res+=querysum(l,r,node[i].rson,mid+,nowr);
else res+=querysum(l,mid,node[i].lson,nowl,mid)+querysum(mid+,r,node[i].rson,mid+,nowr);
return res;
} long long query(int l,int r,int t)
{
return querysum(l,r,rt[t],,n);
} int main()
{
int m;
while (~scanf("%d%d",&n,&m))
{
for (int i=;i<=n;i++) scanf("%d",&a[i]);
ts=tot=;
rt[]=build(,n);
while (m--)
{
char s[];
scanf("%s",s);
if (s[]=='C')
{
int l,r,d;
scanf("%d%d%d",&l,&r,&d);
insert(l,r,d);
}
else if (s[]=='Q')
{
int l,r;
scanf("%d%d",&l,&r);
printf("%I64d\n",query(l,r,ts));
}
else if (s[]=='H')
{
int l,r,t;
scanf("%d%d%d",&l,&r,&t);
printf("%I64d\n",query(l,r,t));
}
else
{
int t;
scanf("%d",&t);
ts=t;
}
}
}
return ;
}