TTM - To the moon

题目链接:TTM - To the moon


区间修改的主席树。

总所周知,主席树区间修改只能标记永久化。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,M=N*40;
int rt[N],sum[M],ls[M],rs[M],add[M],tim,cnt,n,m;	string op;
void build(int &p,int l,int r){
	p=++cnt;	if(l==r){cin>>sum[p]; return ;}
	int mid=l+r>>1;
	build(ls[p],l,mid);	build(rs[p],mid+1,r);
	sum[p]=sum[ls[p]]+sum[rs[p]];
}
void change(int l,int r,int &x,int y,int ql,int qr,int v){
	x=++cnt; sum[x]=sum[y],ls[x]=ls[y],rs[x]=rs[y],add[x]=add[y];
	if(ql==l&&qr==r){add[x]+=v;	return;}	int mid=l+r>>1;
	if(qr<=mid)	change(l,mid,ls[x],ls[y],ql,qr,v);
	else if(ql>mid)	change(mid+1,r,rs[x],rs[y],ql,qr,v);
	else change(l,mid,ls[x],ls[y],ql,mid,v),change(mid+1,r,rs[x],rs[y],mid+1,qr,v);
	sum[x]=sum[ls[x]]+sum[rs[x]]+(mid-l+1)*add[ls[x]]+(r-mid)*add[rs[x]];
}
int ask(int l,int r,int x,int ql,int qr){
	if(l==ql&&r==qr)	return sum[x]+add[x]*(r-l+1);
	int v=(qr-ql+1)*add[x],mid=l+r>>1;
	if(qr<=mid)	return v+ask(l,mid,ls[x],ql,qr);
	else if(ql>mid)	return v+ask(mid+1,r,rs[x],ql,qr);
	else	return ask(l,mid,ls[x],ql,mid)+ask(mid+1,r,rs[x],mid+1,qr)+v;
}
signed main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	cin>>n>>m;	build(rt[0],1,n);
	while(m--){
		cin>>op;	int l,r,x;
		if(op[0]=='B')	cin>>tim;
		if(op[0]=='C')	cin>>l>>r>>x,tim++,change(1,n,rt[tim],rt[tim-1],l,r,x);
		if(op[0]=='Q')	cin>>l>>r,cout<<ask(1,n,rt[tim],l,r)<<'\n';
		if(op[0]=='H')	cin>>l>>r>>x,cout<<ask(1,n,rt[x],l,r)<<'\n';
	}
	return 0;
}
发布了553 篇原创文章 · 获赞 242 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104201242