社区讨论

萌新刚学平衡树,0pts求调

P2042[NOI2005] 维护数列参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@m2fy3zng
此快照首次捕获于
2024/10/19 17:17
去年
此快照最后确认于
2024/10/19 19:29
去年
查看原帖
CPP
/* 云云珂爱! */
#include<bits/stdc++.h>
#define int long long
using namespace std;
string op;
int n,q,cnt=0,rt;
int help[4000005];
struct FHQ_Treap{
	int l,r,siz,val,randval;
	int sum,presum,sufsum,dat;
}Treap[4000005];
int updlazy[4000005],updtag[4000005];
int revlazy[4000005];
void pushup(int p){
	if(!p) return ;
	Treap[p].siz=Treap[Treap[p].l].siz+Treap[Treap[p].r].siz+1;
	if(updtag[p]){
		Treap[p].sum=updlazy[p]*Treap[p].siz;
		if(updlazy[p]>0){
			Treap[p].dat=Treap[p].sum;
			Treap[p].presum=Treap[p].sufsum=Treap[p].sum;
		}else{
			Treap[p].dat=updlazy[p];
			Treap[p].presum=Treap[p].sufsum=0;
		}
	}
	else{
		Treap[p].sum=Treap[Treap[p].l].sum+Treap[Treap[p].r].sum+Treap[p].val;
		Treap[p].presum=max(Treap[p].presum,Treap[Treap[p].l].sum+Treap[p].val+Treap[Treap[p].r].presum);
		Treap[p].sufsum=max(Treap[p].sufsum,Treap[Treap[p].r].sum+Treap[p].val+Treap[Treap[p].l].sufsum);
		Treap[p].dat=max({Treap[Treap[p].l].dat,Treap[Treap[p].r].dat,Treap[Treap[p].l].sufsum+Treap[p].val+Treap[Treap[p].r].presum});
		if(revlazy[p]) swap(Treap[p].presum,Treap[p].sufsum);
	}
	return ; 	
}
void pushdown(int p){
	if(!p) return ;
	if(updtag[p]){
		updlazy[Treap[p].l]=updlazy[p];
		updlazy[Treap[p].r]=updlazy[p];
		updtag[Treap[p].l]=updtag[Treap[p].r]=true;
		Treap[p].val=updlazy[p];
		pushup(Treap[p].l); pushup(Treap[p].r);
	}
	if(revlazy[p]){
		swap(Treap[p].l,Treap[p].r);
		revlazy[Treap[p].l]^=1;
		revlazy[Treap[p].r]^=1;
		swap(Treap[Treap[p].l].presum,Treap[Treap[p].l].sufsum);
		swap(Treap[Treap[p].r].presum,Treap[Treap[p].r].sufsum);
		revlazy[p]=0;
	}
	return ;
}
int Make_new(int x){
	++cnt;
	Treap[cnt].l=Treap[cnt].r=0;
	Treap[cnt].siz=1;
	Treap[cnt].sum=Treap[cnt].val=x;
	Treap[cnt].dat=x;
	Treap[cnt].randval=rand();
	Treap[cnt].presum=Treap[cnt].sufsum=max(0ll,x);
	return cnt;
}
int build(int l,int r){
	if(l>r) return 0;
	if(l==r) return Make_new(help[l]);
	int mid=(l+r)>>1;
	int px=Make_new(help[mid]);
	Treap[px].l=build(l,mid-1);
	Treap[px].r=build(mid+1,r);
	pushup(px);
	return px;
}
void Split(int p,int val,int &l,int &r){
	if(!p){
		l=r=0;
		return ;
	}
	pushdown(p); 
	if(Treap[Treap[p].l].siz+1<=val){ 
		l=p; 
		Split(Treap[p].r,val-Treap[Treap[p].l].siz-1,Treap[p].r,r); 
	}else{
		r=p; 
		Split(Treap[p].l,val,l,Treap[p].l); 
	}
	pushup(p);
	return ;
}
int Merge(int l,int r){
	if(!l||!r){
		pushup(l); pushup(r);
		return l+r;
	}
	pushdown(l); pushdown(r);
	if(Treap[l].randval<=Treap[r].randval){
		Treap[l].r=Merge(Treap[l].r,r);
		pushup(l);
		return l;
	}
	Treap[r].l=Merge(Treap[r].l,l);
	pushup(r);
	return r;
}
void Delete(int x,int len){
	int ll,rr,px;
	Split(rt,x-1,ll,rr);
	Split(rr,len,px,rr);
	rt=Merge(ll,rr);
	return ;
}
void Modify(int x,int len,int val){
	int ll,rr,px;
	Split(rt,x-1,ll,rr);
	Split(rr,len,px,rr);
	updlazy[px]=val; updtag[px]=true;
	pushup(px);
	rt=Merge(Merge(ll,px),rr);
	return ;
}
void Reverse(int x,int len){
	int ll,rr,px;
	Split(rt,x-1,ll,rr);
	Split(rr,len,px,rr);
	revlazy[px]^=1;
	swap(Treap[px].presum,Treap[px].sufsum);
	rt=Merge(Merge(ll,px),rr);
	return ;	
}
int query(int x,int len){
	int ll,rr,px;
	Split(rt,x-1,ll,rr);
	Split(rr,len,px,rr);
	int nowans=Treap[px].sum;
	rt=Merge(Merge(ll,px),rr);
	return nowans;
}
int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*f;
}
signed main(){
	srand(201110191);
	n=read(); q=read();
	for(int i=1;i<=n;i++) help[i]=read();
	Treap[0].dat=-1e18;
	rt=build(1,n);
	while(q--){
		cin>>op;
		if(op=="INSERT"){
			int x,k;
			x=read(); k=read(); 
			for(int i=1;i<=k;i++) help[i]=read();
			int ll,rr;
			Split(rt,x,ll,rr);
			rt=Merge(Merge(ll,build(1,k)),rr);
		} 
		if(op=="DELETE"){
			int x,k;
			x=read(); k=read();
			Delete(x,k);
		}
		if(op=="MAKE-SAME"){
			int x,k,val;
			x=read(); k=read();
			val=read();
			Modify(x,k,val);
		}
		if(op=="REVERSE"){
			int x,k;
			x=read(); k=read();
			Reverse(x,k);
		}
		if(op=="GET-SUM"){
			int x,k;
			x=read(); k=read();
			printf("%lld\n",query(x,k));
		}
		if(op=="MAX-SUM") printf("%lld\n",Treap[rt].dat);
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...