http://acm.hdu.edu.cn/showproblem.php?pid=4348
sb的标记永久化即可,刚开始add和sum没复制过来wa了两发。。。,操作和原来的都一样,出来单点变成区间,还要加一个标记永久化,这样就不用pushdown新加节点而爆内存了
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f; int rt[N],tot,ls[N*],rs[N*];
ll sum[N*],add[N*];
void build(int &o,int l,int r)
{
o=++tot;
add[o]=;
if(l==r)
{
scanf("%lld",&sum[o]);
return ;
}
int m=(l+r)>>;
build(ls[o],l,m);
build(rs[o],m+,r);
sum[o]=sum[ls[o]]+sum[rs[o]];
// printf("%d+++%d+++%d+++%lld+++%d\n",l,r,o,sum[o],add[o]);
}
void update(int &o,int l,int r,int last,int L,int R,int x)
{
o=++tot;
ls[o]=ls[last];
rs[o]=rs[last];
sum[o]=sum[last];
add[o]=add[last];
if(L<=l&&r<=R)
{
add[o]+=x;
return ;
}
int m=(l+r)>>;
if(L<=m)update(ls[o],l,m,ls[last],L,R,x);
if(m<R)update(rs[o],m+,r,rs[last],L,R,x);
sum[o]=sum[ls[o]]+add[ls[o]]*(m-l+)+sum[rs[o]]+add[rs[o]]*(r-m);
// printf("%d %d %lld %lld\n",ls[o],rs[o],sum[ls[o]],sum[rs[o]]);
// printf("%d+++%d+++%d+++%lld+++%d\n",l,r,o,sum[o],add[o]);
}
ll query(int o,ll ad,int l,int r,int L,int R)
{
// printf("%d %d %d %lld\n",l,r,o,ad);
if(L<=l&&r<=R)
return (ad+add[o])*(r-l+)+sum[o];
ll ans=;
int m=(l+r)>>;
if(L<=m)ans+=query(ls[o],ad+add[o],l,m,L,R);
if(m<R)ans+=query(rs[o],ad+add[o],m+,r,L,R);
return ans;
}
char s[];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
build(rt[],,n);
int cnt=;
while(m--)
{
scanf("%s",s);
if(s[]=='Q')
{
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",query(rt[cnt],,,n,l,r));
}
else if(s[]=='C')
{
cnt++;
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
update(rt[cnt],,n,rt[cnt-],l,r,c);
}
else if(s[]=='H')
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
printf("%lld\n",query(rt[c],,,n,l,r));
}
else scanf("%d",&cnt);
}
}
return ;
}
/********************
10 5
1 2 3 4 5 6 7 8 9 10
Q 2 4
C 3 6 3
Q 2 4
********************/