研究Splay的最好方法是......
查看原帖
研究Splay的最好方法是......
1109707
godmoo楼主2023/12/5 18:39

帮我调出这道题 QAQ
模仿神贴应该不至于被封吧
悬赏一关.jpg

#include<bits/stdc++.h>
#define max3(a,b,c) max(a,max(b,c))
using namespace std;
const int N=5e5+5;
const int INF=2e9;
int n,m,tot,rt,data[N],id[N];
stack<int> st;
struct Node{int ch[2],fa,id,val,siz,sum,rev,tag,lmx,rmx,smx;}tree[N];
void pushup(int u){
	tree[u].siz=tree[tree[u].ch[0]].siz+tree[tree[u].ch[1]].siz+1;
	tree[u].sum=tree[tree[u].ch[0]].sum+tree[tree[u].ch[1]].sum+tree[u].val;
	tree[u].lmx=max(tree[tree[u].ch[0]].lmx,tree[tree[u].ch[0]].sum+tree[tree[u].ch[1]].lmx);
	tree[u].rmx=max(tree[tree[u].ch[1]].rmx,tree[tree[u].ch[1]].sum+tree[tree[u].ch[0]].rmx);
	tree[u].smx=max3(tree[tree[u].ch[0]].smx,tree[tree[u].ch[1]].smx,tree[tree[u].ch[0]].rmx+tree[tree[u].ch[1]].lmx);
}
void pushdown(int u){
	if(tree[u].tag){
		if(tree[u].ch[0]){
			tree[tree[u].ch[0]].tag=tree[tree[u].ch[0]].val=tree[u].tag;
			tree[tree[u].ch[0]].sum=tree[tree[u].ch[0]].siz*tree[u].tag;
			tree[tree[u].ch[0]].lmx=tree[tree[u].ch[0]].rmx=max(0,tree[tree[u].ch[0]].sum);
			tree[tree[u].ch[0]].smx=max(tree[tree[u].ch[0]].sum,tree[u].tag);
		}
		if(tree[u].ch[1]){
			tree[tree[u].ch[1]].tag=tree[tree[u].ch[1]].val=tree[u].tag;
			tree[tree[u].ch[1]].sum=tree[tree[u].ch[1]].siz*tree[u].tag;
			tree[tree[u].ch[1]].lmx=tree[tree[u].ch[1]].rmx=max(0,tree[tree[u].ch[1]].sum);
			tree[tree[u].ch[1]].smx=max(tree[tree[u].ch[1]].sum,tree[u].tag);
		}
		tree[u].tag=tree[u].rev=0;
	}
	if(tree[u].rev){
		tree[tree[u].ch[0]].rev^=1,tree[tree[u].ch[1]].rev^=1;
		swap(tree[u].ch[0],tree[u].ch[1]);
		tree[u].rev=0;
	}
}
int create(int id,int fa,int num[],int idx[]){
	tree[idx[id]].id=idx[id];
	tree[idx[id]].val=num[id];
	tree[idx[id]].fa=fa;
	return idx[id];
}
void build(int &u,int l,int r,int fa,int num[],int idx[]){
	if(l>r) return;
	int mid=l+r>>1;
	u=create(mid,fa,num,idx);
	build(tree[u].ch[0],l,mid-1,u,num,idx);
	build(tree[u].ch[1],mid+1,r,u,num,idx);
	pushup(u);
}
void recycle(int u){
	if(!u) return;
	tree[u].ch[0]=tree[u].ch[1]=tree[u].fa=tree[u].id=tree[u].val=tree[u].siz=tree[u].sum=tree[u].tag=tree[u].rev=tree[u].lmx=tree[u].rmx=tree[u].smx=0;
	st.push(u);
	recycle(tree[u].ch[0]),recycle(tree[u].ch[1]);
}
bool check(int u){return tree[tree[u].fa].ch[1];}
void rotate(int u){
	int fa=tree[u].fa,ffa=tree[fa].fa,k=check(u),p=check(fa);
	tree[fa].ch[k]=tree[u].ch[!k],tree[tree[u].ch[!k]].fa=fa;
	tree[u].ch[!k]=fa,tree[fa].fa=u;
	tree[ffa].ch[p]=u,tree[u].fa=ffa;
	pushup(fa),pushup(u);
}
void splay(int u,int goal){
	while(tree[u].fa!=goal){
		int fa=tree[u].fa,ffa=tree[fa].fa;
		if(ffa!=goal) check(u)^check(fa)?rotate(u):rotate(fa);
		rotate(u);
	}
	if(!goal) rt=u;
}
int kth(int x){
	int u=rt;
    while(1){
        pushdown(u);
        if(x<=tree[tree[u].ch[0]].siz) u=tree[u].ch[0];
        else if(x==tree[tree[u].ch[0]].siz+1) return u;
        else x-=tree[tree[u].ch[0]].siz+1,u=tree[u].ch[1];
    }
}
int split(int pos,int l){
	int x=kth(pos),y=kth(pos+l+1);
	splay(x,0),splay(y,x);
	return tree[y].ch[0];
}
void insert(int pos,int l,int num[]){
	int tmprt,tmpid[N];
	for(int i=1;i<=l;i++){
		if(st.empty()) tmpid[i]= ++tot;
		else tmpid[i]=st.top(),st.pop();
	}
	build(tmprt,1,l,0,num,tmpid);
	int x=kth(pos),y=kth(pos+1);
	tree[y].ch[0]=tmprt,tree[tmprt].fa=y;
	pushup(y),pushup(x);
}
void remove(int pos,int l){
	int u=split(pos,l),fa=tree[u].fa;
	recycle(u),tree[fa].ch[0]=0;
	pushup(fa),pushup(rt);
}
void assign(int pos,int l,int k){
	int u=split(pos,l);
	tree[u].tag=tree[u].val=k;
	tree[u].sum=tree[u].siz*k;
	tree[u].lmx=tree[u].rmx=max(0,tree[u].sum);
	tree[u].smx=max(k,tree[u].sum);
	pushup(tree[u].fa),pushup(rt);
}
void flip(int pos,int l){
	int u=split(pos,l);
	tree[u].rev^=1;
}
int query_sum(int pos,int l){
	int u=split(pos,l);
	return tree[u].sum;
}
int query_max_sum(){return tree[rt].smx;}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n+1;i++) scanf("%d",data+i);
	for(int i=1;i<=n+2;i++) id[i]=i;
	build(rt,1,n+2,0,data,id),tot=n+2;
	tree[1].val=tree[n+2].val=tree[0].smx=-INF;
	for(int i=1,pos,l,k,tmp[N];i<=m;i++){
		char op[10];
		scanf("%s",op);
		if(op[0]=='I'){
			scanf("%d%d",&pos,&l);
			for(int j=1;j<=l;j++) scanf("%d",tmp+j);
			insert(pos,l,tmp);
		}
		if(op[0]=='D') scanf("%d%d",&pos,&l),remove(pos,l);
		if(op[0]=='M'&&op[2]=='K') scanf("%d%d%d",&pos,&l,&k),assign(pos,l,k);
		if(op[0]=='R') scanf("%d%d",&pos,&l),flip(pos,l);
		if(op[0]=='G') scanf("%d%d",&pos,&l),printf("%d\n",query_sum(pos,l));
		if(op[0]=='M'&&op[2]=='X') printf("%d\n",query_max_sum());
	}
	return 0;
}
2023/12/5 18:39
加载中...