Solution Set - Splay

A[洛谷P3369]维护集合,支持插入,删除,查询\(x\)的排名,查询排名\(x\)的数,查询前驱,查询后继。
B[洛谷P3391]维护一个序列,支持区间翻转。
C[洛谷P3380]维护数列,支持单点修改,在某区间内查询\(x\)的排名,排名为\(x\)的数,前驱,后继。
D[洛谷P4036]维护一个字符串,支持单点修改,单点插入,询问两端后缀的最长公共前缀。
E[洛谷P4309]依次将\(1,2,...,n\)插入一个数列中,询问每次插入后的LIS。
F[洛谷P2042]维护一个数列,支持单点插入,区间删除,区间覆盖,区间翻转,查询区间和,查询最大子串和。
G[POJ3580]维护一个数列,支持区间加,区间翻转,区间轮换,单点插入,单点删除,查询区间最小值。
H[洛谷P3215]维护一个括号序列,支持区间覆盖,区间翻转,区间取反,查询将某个区间变为合法至少需要修改的括号数。
I[洛谷P3224]维护一张图,支持连边,查询与某个点连通的点中的第\(k\)小点权。


Splay:伸展树,是一种二叉搜索树,基本操作为旋转和伸展(即将某个点旋转到根)。均摊\(O(n\log n)\)
Splay相当灵活,常用的处理手段是把点\(l-1\)转到根,再把\(r+1\)转到\(l-1\)的右儿子,此时\(r+1\)的左儿子代表区间\([l,r]\)
在此基础上,可以像线段树一样用儿子更新信息,打懒惰标记。

A平衡树模板。
B使用懒标记的模板。注意在维护下标的平衡树,在平衡树的中序遍历中位于第\(k\)位的点就代表数列中第\(k\)个数。
C线段树套平衡树,在线段树的每个点开平衡树记录该区间的所有数。
D平衡树维护字符串哈希值,只需要修改push_up即可。询问时二分。
E注意到每次插入不影响已插入的点的DP值,故直接维护即可。
F,G都是懒标记,注意每次提取区间,打标记之后都要push_up。求最大子串和可以维护前缀最大和后缀最大。
H记录把()看做匹配,左边留下的)数和右边留下的(数,以及取反之后的结果,Splay维护即可。
I平衡树的启发式合并。


点击查看A题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,INF=1e9;
int n;
struct Splay{
	int rt,tot,fa[N],ch[N][2],val[N],cnt[N],siz[N];
	void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+cnt[p];}
	bool get(int p){return p==ch[fa[p]][1];}
	void clear(int p){fa[p]=ch[p][0]=ch[p][1]=val[p]=cnt[p]=siz[p]=0;}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=1-get(x);
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int x,int goal=0){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt=x;
	}
	void ins(int v){
		if(!tot){rt=tot=1;val[1]=v;cnt[1]=siz[1]=1;return;}
		int p=rt,f=0;
		while(1){
			if(val[p]==v){++cnt[p];++siz[p];push_up(f);splay(p);break;}
			f=p;p=ch[p][val[p]<v];
			if(!p){
				val[p=++tot]=v;cnt[p]=siz[p]=1;
				fa[tot]=f;ch[f][val[f]<v]=p;
				push_up(f);splay(p);break;
			}
		}
	}
	bool find(int v){
		int p=rt;
		while(p){
			if(val[p]==v){splay(p);return true;}
			p=ch[p][val[p]<v];
		}return false;
	}
	void merge(int x,int y){
		while(ch[x][1])x=ch[x][1];
		splay(x);ch[x][1]=y;fa[y]=x;push_up(x);
	}
	void del(int v){
		if(!find(v))return;
		if(cnt[rt]>1){--cnt[rt],--siz[rt];return;}
		int x=ch[rt][0],y=ch[rt][1];
		fa[x]=fa[y]=0;clear(rt);
		if(!x||!y){rt=x+y;return;}
		merge(x,y);
	}
	int rank(int v){
		find(v);
		return siz[ch[rt][0]]+1;
	}
	int kth(int k){
		int p=rt;
		while(1){
			if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
			else{
				k-=cnt[p]+siz[ch[p][0]];
				if(k<=0){splay(p);return val[p];}
				p=ch[p][1];
			}
		}
	}
	int nxt(int x,int op){
		ins(x);int p=ch[rt][op^1];
		if(!p)return -1;
		while(ch[p][op])p=ch[p][op];
		int res=val[p];del(x);
		return res;
	}
}cst;
int main(){
	scanf("%d",&n);
	cst.ins(INF);cst.ins(-INF);
	for(int i=1,op,x;i<=n;i++){
		scanf("%d%d",&op,&x);
		if(op==1)cst.ins(x);
		if(op==2)cst.del(x);
		if(op==3)printf("%d\n",cst.rank(x)-1);
		if(op==4)printf("%d\n",cst.kth(x+1));
		if(op==5)printf("%d\n",cst.nxt(x,1));
		if(op==6)printf("%d\n",cst.nxt(x,0));
	}
	return 0;
}
点击查看B题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,ans[N],cnt;
struct Splay{
	int rt,tot,fa[N],ch[N][2],val[N],tag[N],siz[N];
	void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;}
	int build(int l,int r){
		if(l==r){push_up(l);return l;}
		int p=l+r>>1;
		if(l<p)fa[ch[p][0]=build(l,p-1)]=p;
		if(p<r)fa[ch[p][1]=build(p+1,r)]=p;
		push_up(p);
		return p;
	}
	bool get(int p){return p==ch[fa[p]][1];}
	void push_down(int p){
		if(!tag[p])return;
		tag[ch[p][0]]^=1;tag[ch[p][1]]^=1;
		tag[p]=0;swap(ch[p][0],ch[p][1]);
	}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=get(x)^1;
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int x,int goal){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt=x;
	}
	int kth(int k){
		int p=rt;
		while(1){
			push_down(p);
			if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
			else{
				k-=siz[ch[p][0]]+1;
				if(k<=0)return p;
				p=ch[p][1];
			}
		}
	}
	void update(int l,int r){
		l=kth(l-1);splay(l,0);
		r=kth(r+1);splay(r,l);
		tag[ch[r][0]]^=1;
	}
	void dfs(int p){
		push_down(p);
		if(ch[p][0])dfs(ch[p][0]);
		if(p!=1&&p!=n+2)printf("%d ",p-1);
		if(ch[p][1])dfs(ch[p][1]);
	}
}cst;
int main(){
	scanf("%d%d",&n,&m);
	cst.rt=cst.build(1,n+2);
	for(int i=1,l,r;i<=m;i++){
		scanf("%d%d",&l,&r);
		cst.update(l+1,r+1);
	}
	cst.dfs(cst.rt);
	return 0;
}
点击查看C题代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5,M=2.22e7+5,INF=2147483647;
int n,m,a[N];
struct Splay{
	int rt[N*10],tot,fa[M],ch[M][2],val[M],cnt[M],siz[M];
	void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+cnt[p];}
	bool get(int p){return p==ch[fa[p]][1];}
	void clear(int p){fa[p]=ch[p][0]=ch[p][1]=val[p]=cnt[p]=siz[p]=0;}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=get(x)^1;
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int id,int x,int goal=0){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt[id]=x;
	}
	void ins(int id,int v){
		if(!rt[id]){rt[id]=++tot;val[tot]=v;cnt[tot]=siz[tot]=1;return;}
		int p=rt[id],f=0;
		while(1){
			if(val[p]==v){++cnt[p];++siz[p];push_up(f);splay(id,p);break;}
			f=p;p=ch[p][val[p]<v];
			if(!p){
				val[p=++tot]=v;cnt[p]=siz[p]=1;
				fa[p]=f;ch[f][val[f]<v]=p;
				push_up(f);splay(id,p);break;
			}
		}
	}
	bool find(int id,int v){
		int p=rt[id];
		while(1){
			if(val[p]==v){splay(id,p);return true;}
			p=ch[p][val[p]<v];
		}return false;
	}
	void merge(int id,int x,int y){
		while(ch[x][1])x=ch[x][1];
		splay(id,x);ch[x][1]=y;fa[y]=x;push_up(x);
	}
	void del(int id,int v){
		if(!find(id,v))return;
		if(cnt[rt[id]]>1){--cnt[rt[id]];--siz[rt[id]];return;}
		int x=ch[rt[id]][0],y=ch[rt[id]][1];
		fa[x]=fa[y]=0;clear(rt[id]);
		if(!x||!y)rt[id]=x+y;else merge(id,x,y);
	}
	int rank(int id,int v){
		int p=rt[id],res=0;
		while(p){
			if(v<val[p])p=ch[p][0];
			else{
				res+=siz[ch[p][0]];
				if(v==val[p]){splay(id,p);return res;}
				res+=cnt[p];p=ch[p][1];
			}
		}
		return res;
	}
	int nxt(int id,int v,int op){
		ins(id,v);int p=ch[rt[id]][op^1];
		if(!p){del(id,v);return op?-INF:INF;}
		while(ch[p][op])p=ch[p][op];
		int res=val[p];splay(id,p);del(id,v);
		return res;
	}
}cst;
struct SegmentTree{
	#define ls p<<1
	#define rs p<<1|1
	#define mid (l+r>>1)
	void modify(int p,int l,int r,int x,int v,int op){
		if(!op)cst.del(p,v);else cst.ins(p,v);
		if(l==r)return;
		if(x<=mid)modify(ls,l,mid,x,v,op);
		else modify(rs,mid+1,r,x,v,op);
	}
	int query_rank(int p,int l,int r,int L,int R,int v){
		if(l>=L&&r<=R)return cst.rank(p,v);
		if(R<=mid)return query_rank(ls,l,mid,L,R,v);
		if(L>mid)return query_rank(rs,mid+1,r,L,R,v);
		return query_rank(ls,l,mid,L,R,v)+query_rank(rs,mid+1,r,L,R,v);
	}
	int query_kth(int L,int R,int k){
		int l=0,r=1e8,res=0;
		while(l<=r){
			int MID=mid;
			if(query_rank(1,1,n,L,R,MID)>k)r=MID-1;
			else l=MID+1,res=MID;
		}
		return res;
	}
	int query_nxt(int p,int l,int r,int L,int R,int v,int op){
		if(l>=L&&r<=R)return cst.nxt(p,v,op);
		if(R<=mid)return query_nxt(ls,l,mid,L,R,v,op);
		if(L>mid)return query_nxt(rs,mid+1,r,L,R,v,op);
		return op?max(query_nxt(ls,l,mid,L,R,v,op),query_nxt(rs,mid+1,r,L,R,v,op)):
				  min(query_nxt(ls,l,mid,L,R,v,op),query_nxt(rs,mid+1,r,L,R,v,op));
	}
}seg;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",a+i),seg.modify(1,1,n,i,a[i],1);
	for(int i=1,op,l,r,x;i<=m;i++){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",seg.query_rank(1,1,n,l,r,x)+1);
		}
		if(op==2){
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",seg.query_kth(l,r,x-1));
		}
		if(op==3){
			scanf("%d%d",&l,&x);
			seg.modify(1,1,n,l,a[l],0);a[l]=x;
			seg.modify(1,1,n,l,a[l],1);
		}
		if(op==4){
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",seg.query_nxt(1,1,n,l,r,x,1));
		}
		if(op==5){
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",seg.query_nxt(1,1,n,l,r,x,0));
		}
	}
	return 0;
}
点击查看D题代码
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=1e5+5;
int n,m,x,y;char s[N],op[3],ch[3];ull r[N],base=131;
struct Splay{
	int rt,tot,fa[N],ch[N][2],siz[N];ull val[N],h[N];
	void push_up(int p){
		h[p]=h[ch[p][0]]+val[p]*r[siz[ch[p][0]]]+h[ch[p][1]]*r[siz[ch[p][0]]+1];
		siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
	}
	bool get(int p){return p==ch[fa[p]][1];}
	void clear(int p){fa[p]=ch[p][0]=ch[p][1]=siz[p]=val[p]=h[p]=0;}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=get(x)^1;
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int x,int goal=0){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt=x;
	}
	int build(int l,int r){
		int mid=l+r>>1;val[mid]=s[mid];
		if(l<mid)fa[ch[mid][0]=build(l,mid-1)]=mid;
		if(r>mid)fa[ch[mid][1]=build(mid+1,r)]=mid;
		push_up(mid);return mid;
	}
	int find(int x){
		int p=rt;
		while(1){
			if(siz[ch[p][0]]>=x)p=ch[p][0];
			else if(siz[ch[p][0]]==x-1)return p;
			else x-=siz[ch[p][0]]+1,p=ch[p][1];
		}
	}
	ull query(int l,int r){
		l=find(l-1);splay(l);r=find(r+1);splay(r,l);
		return h[ch[r][0]];
	}
	void modify(int x,char c){splay(find(x));val[rt]=c;push_up(rt);}
	void ins(int x,char c){
		int l=find(x);splay(l);int r=find(x+1);splay(r,l);
		ch[ch[rt][1]][0]=++tot;fa[tot]=ch[rt][1];val[tot]=h[tot]=c;
		splay(tot);
	}
}cst;
int main(){
	r[0]=1;for(int i=1;i<N;i++)r[i]=r[i-1]*base;
	scanf("%s",s+2);n=strlen(s+2);
	cst.rt=cst.build(1,n+2);cst.tot=n+2;
	scanf("%d",&m);
	while(m--){
		scanf("%s",op);
		if(op[0]=='Q'){
			scanf("%d%d",&x,&y);
			int l=1,r=min(n-x+1,n-y+1),res=0;
			while(l<=r){
				int mid=l+r>>1;
				if(cst.query(x+1,x+mid)==cst.query(y+1,y+mid))
					res=mid,l=mid+1;
				else r=mid-1;
			}
			printf("%d\n",res);
		}
		if(op[0]=='R'){scanf("%d",&x);scanf("%s",ch);cst.modify(x+1,ch[0]);}
		if(op[0]=='I'){scanf("%d",&x);scanf("%s",ch);++n;cst.ins(x+1,ch[0]);}
	}
	return 0;
}
点击查看E题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,ans;
struct Splay{
	int rt,tot,fa[N],ch[N][2],siz[N],mx[N],dp[N];
	void init(){rt=1;tot=2;ch[1][1]=2;fa[2]=1;siz[1]=2;siz[2]=1;}
	void push_up(int p){
		mx[p]=max(max(mx[ch[p][0]],mx[ch[p][1]]),dp[p]);
		siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
	}
	bool get(int p){return p==ch[fa[p]][1];}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=get(x)^1;
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int x,int goal=0){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt=x;
	}
	int kth(int k){
		int p=rt;
		while(1){
			if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
			else{
				k-=siz[ch[p][0]]+1;
				if(k<=0)return p;
				p=ch[p][1];
			}
		}
	}
	void update(int x){
		int l=kth(x+1);splay(l);
		int r=kth(x+2);splay(r,l);
		ch[r][0]=++tot;fa[tot]=r;siz[tot]=1;splay(tot);
		dp[rt]=mx[ch[rt][0]]+1;
		printf("%d\n",ans=max(ans,dp[rt]));
	}
}cst;
int main(){
	scanf("%d",&n);cst.init();
	for(int i=1,x;i<=n;i++){scanf("%d",&x);cst.update(x);}
	return 0;
}
//
点击查看F题代码
#include<bits/stdc++.h>
using namespace std;
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^48),ch=getchar();
	return x*f;
}
const int N=3e6+5,INF=1e9;
int n,m,a[N];char opt[15];
struct Splay{
	int rt,tot,fa[N],ch[N][2],siz[N];
	int tag[N],tag2[N],val[N],sum[N],lmx[N],rmx[N],mx[N]={-INF};
	void clear(int p){
		fa[p]=ch[p][0]=ch[p][1]=siz[p]=val[p]=0;
		tag[p]=sum[p]=0;tag2[p]=lmx[p]=rmx[p]=mx[p]=-INF;
	}
	void push_up(int p){
		siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
		if(siz[p]==1){sum[p]=lmx[p]=rmx[p]=mx[p]=val[p];return;}
		sum[p]=sum[ch[p][0]]+sum[ch[p][1]]+val[p];
		lmx[p]=max(lmx[ch[p][0]],sum[ch[p][0]]+val[p]+max(0,lmx[ch[p][1]]));
		rmx[p]=max(rmx[ch[p][1]],sum[ch[p][1]]+val[p]+max(0,rmx[ch[p][0]]));
		mx[p]=max(max(mx[ch[p][0]],mx[ch[p][1]]),
				  max(rmx[ch[p][0]],0)+val[p]+max(lmx[ch[p][1]],0));
	}
	void push_down(int p){
		int lc=ch[p][0],rc=ch[p][1];
		if(tag2[p]!=-INF){
			int v=tag2[p];tag2[p]=-INF;
			if(lc)tag2[lc]=val[lc]=v,sum[lc]=siz[lc]*v,
				  lmx[lc]=rmx[lc]=mx[lc]=v<=0?v:siz[lc]*v;
			if(rc)tag2[rc]=val[rc]=v,sum[rc]=siz[rc]*v,
				  lmx[rc]=rmx[rc]=mx[rc]=v<=0?v:siz[rc]*v;
		}
		if(tag[p]){
			if(lc)tag[lc]^=1,swap(ch[lc][0],ch[lc][1]),swap(lmx[lc],rmx[lc]);
			if(rc)tag[rc]^=1,swap(ch[rc][0],ch[rc][1]),swap(lmx[rc],rmx[rc]);
			tag[p]=0;
		}
	}
	int build(int l,int r){
		if(l==r){val[l]=a[l];tag2[l]=-INF;push_up(l);return l;}
		int p=l+r>>1;val[p]=a[p];tag2[p]=-INF;
		if(l<p)fa[ch[p][0]=build(l,p-1)]=p;
		if(p<r)fa[ch[p][1]=build(p+1,r)]=p;
		push_up(p);return p;
	}
	bool get(int p){return p==ch[fa[p]][1];}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=get(x)^1;
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int x,int goal=0){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt=x;
	}
	int kth(int k){
		int p=rt;
		while(1){
			push_down(p);
			if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
			else{k-=siz[ch[p][0]]+1;if(k<=0)return p;p=ch[p][1];}
		}
	}
	void ins(int p,int v){
		int x=kth(p),y=kth(p+1);
		splay(x);splay(y,x);
		ch[y][0]=++tot;fa[tot]=y;tag2[tot]=-INF;
		val[tot]=v;push_up(tot);splay(tot);
	}
	void range(int&l,int&r){
		l=kth(l);r=kth(r+2);
		splay(l);splay(r,l);
		push_up(r);push_up(l);
	}
	void del(int l,int r){range(l,r);clear(ch[r][0]);ch[r][0]=0;}
	void update1(int l,int r){
		range(l,r);int p=ch[r][0];tag[p]^=1;
		swap(ch[p][0],ch[p][1]);swap(lmx[p],rmx[p]);
	}
	void update2(int l,int r,int v){
		range(l,r);int p=ch[r][0];
		tag2[p]=val[p]=v;sum[p]=siz[p]*v;
		lmx[p]=rmx[p]=mx[p]=v<=0?v:siz[p]*v;
	}
	int query(int l,int r){range(l,r);return sum[ch[r][0]];}
	int maxsum(int l,int r){range(l,r);return mx[ch[r][0]];}
}cst;
int main(){
	n=read();m=read(); 
	for(int i=2;i<=n+1;i++)a[i]=read();
	cst.rt=cst.build(1,n+2);cst.tot=n+2;
	while(m--){
		scanf("%s",opt);
		if(opt[2]=='S'){
			int p=read()+1,k=read();n+=k;
			while(k--)cst.ins(p,read()),++p;
		}
		if(opt[2]=='L'){
			int p=read(),k=read();n-=k;
			if(k)cst.del(p,p+k-1);
		}
		if(opt[2]=='K'){
			int p=read(),k=read(),c=read();
			if(k)cst.update2(p,p+k-1,c);
		}
		if(opt[2]=='V'){
			int p=read(),k=read();
			if(k)cst.update1(p,p+k-1);
		}
		if(opt[2]=='T'){
			int p=read(),k=read();
			if(k)printf("%d\n",cst.query(p,p+k-1));else printf("0\n");
		}
		if(opt[2]=='X')printf("%d\n",cst.maxsum(1,n));
	}
	return 0;
}
点击查看G题代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
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^48),ch=getchar();
	return x*f;
}
const int N=2e5+5,INF=1e9;
int n,m,a[N];char opt[15];
struct Splay{
	int rt,tot,fa[N],ch[N][2],siz[N];
	int tag[N],tag2[N],val[N],mn[N];
	void clear(int p){
		fa[p]=ch[p][0]=ch[p][1]=siz[p]=val[p]=0;
		tag[p]=tag2[p]=0;mn[p]=INF;
	}
	void push_up(int p){
		siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;
		mn[p]=min(min(mn[ch[p][0]],mn[ch[p][1]]),val[p]);
	}
	void push_down(int p){
		int lc=ch[p][0],rc=ch[p][1];
		if(tag2[p]){
			int v=tag2[p];tag2[p]=0;
			if(lc)val[lc]+=v,mn[lc]+=v,tag2[lc]+=v;
			if(rc)val[rc]+=v,mn[rc]+=v,tag2[rc]+=v;
		}
		if(tag[p]){
			if(lc)tag[lc]^=1,swap(ch[lc][0],ch[lc][1]);
			if(rc)tag[rc]^=1,swap(ch[rc][0],ch[rc][1]);
			tag[p]=0;
		}
	}
	int build(int l,int r){
		if(l==r){val[l]=a[l];push_up(l);return l;}
		int p=l+r>>1;val[p]=a[p];
		if(l<p)fa[ch[p][0]=build(l,p-1)]=p;
		if(p<r)fa[ch[p][1]=build(p+1,r)]=p;
		push_up(p);return p;
	}
	bool get(int p){return p==ch[fa[p]][1];}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=get(x)^1;
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int x,int goal=0){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt=x;
	}
	int kth(int k){
		int p=rt;
		while(1){
			push_down(p);
			if(ch[p][0]&&k<=siz[ch[p][0]])p=ch[p][0];
			else{k-=siz[ch[p][0]]+1;if(k<=0)return p;p=ch[p][1];}
		}
	}
	void ins(int p,int v){
		int x=kth(p),y=kth(p+1);
		splay(x);splay(y,x);
		ch[y][0]=++tot;fa[tot]=y;
		val[tot]=v;push_up(tot);splay(tot);
	}
	void range(int&l,int&r){
		l=kth(l);r=kth(r+2);
		splay(l);splay(r,l);
		push_up(r);push_up(l);
	}
	void del(int l,int r){range(l,r);clear(ch[r][0]);ch[r][0]=0;}
	void move(int l,int r,int t){
		int len=r-l+1;t=(t%len+len)%len;if(!t)return; 
		int x=l,y=r-t;range(x,y);int p=ch[y][0];ch[y][0]=fa[p]=0;push_up(y);
		x=l+t;y=l+t-1;range(x,y);ch[y][0]=p;fa[p]=y;push_up(y);
	}
	void update1(int l,int r){
		range(l,r);int p=ch[r][0];tag[p]^=1;
		swap(ch[p][0],ch[p][1]);
	}
	void update2(int l,int r,int v){
		range(l,r);int p=ch[r][0];
		tag2[p]+=v;val[p]+=v;mn[p]+=v;
	}
	int query(int l,int r){range(l,r);return mn[ch[r][0]];}
	void print(int p){
		push_down(p);
		if(ch[p][0])print(ch[p][0]);
		printf("%d ",val[p]);
		if(ch[p][1])print(ch[p][1]);
	}
}cst;
int main(){
	n=read();cst.mn[0]=INF;
	for(int i=2;i<=n+1;i++)a[i]=read();
	cst.rt=cst.build(1,n+2);cst.tot=n+2;
	m=read();
	while(m--){
		scanf("%s",opt);
		if(opt[0]=='A'){int l=read(),r=read(),c=read();cst.update2(l,r,c);}
		if(opt[0]=='R'&&opt[3]=='E'){int l=read(),r=read();cst.update1(l,r);}
		if(opt[0]=='R'&&opt[3]=='O'){int l=read(),r=read(),t=read();cst.move(l,r,t);}
		if(opt[0]=='I'){int p=read(),v=read();cst.ins(p+1,v);}
		if(opt[0]=='D'){int p=read();cst.del(p,p);}
		if(opt[0]=='M'){int l=read(),r=read();printf("%d\n",cst.query(l,r));}
	}
	return 0;
}

点击查看H题代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m;char s[N],opt[10],ch[3];
struct Splay{
	int rt,fa[N],ch[N][2],siz[N],val[N];
	int lef[N][2],rig[N][2],tag1[N],tag2[N],tag3[N];
	void push_up(int p){
		int lc=ch[p][0],rc=ch[p][1],l1,r1,l2,r2;
		siz[p]=siz[lc]+siz[rc]+1;
		l1=lef[lc][0];r1=rig[lc][0];l2=lef[rc][0];r2=rig[rc][0];
		if(val[p]==-1)++r1;if(val[p]==1)++l2;
		lef[p][0]=l1+l2-min(r1,l2);rig[p][0]=r1+r2-min(r1,l2);
		l1=lef[lc][1];r1=rig[lc][1];l2=lef[rc][1];r2=rig[rc][1];
		if(val[p]==-1)++l2;if(val[p]==1)++r1;
		lef[p][1]=l1+l2-min(r1,l2);rig[p][1]=r1+r2-min(r1,l2);
	}
	void tag(int p,int op){
		if(op==2){
			tag2[p]^=1;swap(ch[p][0],ch[p][1]);
			swap(lef[p][0],rig[p][1]);swap(lef[p][1],rig[p][0]);
		}
		else if(op==3){
			tag3[p]^=1;val[p]=-val[p];
			swap(lef[p][0],lef[p][1]);swap(rig[p][0],rig[p][1]);
		}
		else{
			tag1[p]=val[p]=op;tag3[p]=0;
			lef[p][0]=rig[p][1]=(val[p]==1?siz[p]:0);
			rig[p][0]=lef[p][1]=(val[p]==1?0:siz[p]);
		}
	}
	void push_down(int p){
		int lc=ch[p][0],rc=ch[p][1];
		if(tag1[p]){if(lc)tag(lc,tag1[p]);if(rc)tag(rc,tag1[p]);tag1[p]=0;}
		if(tag2[p]){tag2[p]=0;if(lc)tag(lc,2);if(rc)tag(rc,2);}
		if(tag3[p]){tag3[p]=0;if(lc)tag(lc,3);if(rc)tag(rc,3);}
	}
	int build(int l,int r){
		if(l>r)return 0;
		int p=l+r>>1;if(s[p]=='(')val[p]=-1;if(s[p]==')')val[p]=1;
		ch[p][0]=build(l,p-1);if(ch[p][0])fa[ch[p][0]]=p;
		ch[p][1]=build(p+1,r);if(ch[p][1])fa[ch[p][1]]=p;
		push_up(p);return p;
	}
	bool get(int p){return p==ch[fa[p]][1];}
	void rotate(int x){
		int y=fa[x],z=fa[y],op=get(x)^1;
		ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
		ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
		push_up(y);push_up(x);
	}
	void splay(int x,int goal=0){
		for(int p=fa[x];p!=goal;p=fa[x]){
			if(fa[p]!=goal)rotate(get(p)==get(x)?p:x);
			rotate(x);
		}if(!goal)rt=x;
	}
	int kth(int k){
		int p=rt;
		while(1){
			push_down(p);
			if(siz[ch[p][0]]>=k)p=ch[p][0];
			else if(siz[ch[p][0]]+1==k)return p;
			else k-=siz[ch[p][0]]+1,p=ch[p][1];
		}
	}
	void range(int&l,int&r){l=kth(l);r=kth(r+2);splay(l);splay(r,l);}
	void update(int l,int r,int op){
		range(l,r);tag(ch[r][0],op);
		push_up(r);push_up(l);
	}
	int query(int l,int r){
		range(l,r);int p=ch[r][0];
		return (lef[p][0]+rig[p][0])/2+(lef[p][0]&1);
	}
}cst;
int main(){
	scanf("%d%d",&n,&m);
	scanf("%s",s+2);
	cst.rt=cst.build(1,n+2);
	for(int i=1,l,r;i<=m;i++){
		scanf("%s",opt);scanf("%d%d",&l,&r);
		if(opt[0]=='R'){scanf("%s",ch);cst.update(l,r,ch[0]=='('?-1:1);}
		if(opt[0]=='S')cst.update(l,r,2);
		if(opt[0]=='I')cst.update(l,r,3);
		if(opt[0]=='Q')printf("%d\n",cst.query(l,r));
	}
	return 0;
}
点击查看I题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,q;char op[3];
int rt[N],len[N],b[N],tot,fa[N*60],ch[N*60][2],val[N*60][2],siz[N*60];
void push_up(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;}
bool get(int p){return p==ch[fa[p]][1];}
void rotate(int x){
	int y=fa[x],z=fa[y],op=get(x)^1;
	ch[y][op^1]=ch[x][op];if(ch[x][op])fa[ch[x][op]]=y;
	ch[x][op]=y;fa[y]=x;fa[x]=z;if(z)ch[z][y==ch[z][1]]=x;
	push_up(y);push_up(x);
}
void splay(int id,int x){
	for(int p=fa[x];p;p=fa[x]){
		if(fa[p])rotate(get(p)==get(x)?p:x);
		rotate(x);
	}rt[id]=x;
}
void ins(int id,int v,int w){
	b[w]=id;++len[id];
	if(!rt[id]){
		rt[id]=++tot;siz[tot]=1;
		val[tot][0]=v;val[tot][1]=w;
		return;
	}
	int p=rt[id],f=0;
	while(1){
		f=p;p=ch[p][val[p][0]<v];
		if(!p){
			val[p=++tot][0]=v;val[p][1]=w;siz[p]=1;
			fa[p]=f;ch[f][val[f][0]<v]=p;
			push_up(f);splay(id,p);break;
		}
	}
}
void merge(int p,int id){
	ins(id,val[p][0],val[p][1]);
	if(ch[p][0])merge(ch[p][0],id);
	if(ch[p][1])merge(ch[p][1],id);
}
int kth(int id,int k){
	int p=rt[id];
	while(1){
		if(siz[ch[p][0]]>=k)p=ch[p][0];
		else{
			k-=siz[ch[p][0]]+1;
			if(k<=0){splay(id,p);return val[p][1];}
			p=ch[p][1];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,x;i<=n;i++){scanf("%d",&x);ins(i,x,i);}
	for(int i=1,x,y;i<=m;i++){
		scanf("%d%d",&x,&y);
		if(len[b[x]]<len[b[y]])swap(x,y);
		merge(rt[b[y]],b[x]);
	}
	scanf("%d",&q);
	for(int i=1,x,y;i<=q;i++){
		scanf("%s",op);scanf("%d%d",&x,&y);
		if(op[0]=='Q'){
			if(len[b[x]]<y)printf("-1\n");
			else printf("%d\n",kth(b[x],y));
		}
		else{
			if(len[b[x]]<len[b[y]])swap(x,y);
			merge(rt[b[y]],b[x]);
		}
	}
	return 0;
}
posted @ 2023-06-10 07:28  by_chance  阅读(3)  评论(0编辑  收藏  举报