Splay 求助,悬赏1关
查看原帖
Splay 求助,悬赏1关
518232
Sternenlicht楼主2023/5/7 12:46
#include <bits/stdc++.h>
namespace IO{
	#define LL long long
	inline LL read(){
		LL x=0,f=1;char c=getchar();
		for (;!isdigit(c);c=getchar())if (c=='-')f=-1;
		for (;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
		return x*f;
	}
	inline void write(LL x,char c='\n'){
		if (x){
			if (x<0)x=-x,putchar('-');
			char a[30];short l;
			for (l=0;x;x/=10)a[l++]=x%10^48;
			for (l--;l>=0;l--)putchar(a[l]);
		}else putchar('0');putchar(c);
	}
}using namespace IO;
using namespace std;

//Splay
const int N = 2e6+10;
struct Splay{int l,r,siz,fa;char val;}tree[N];
int cnt,root;char str[N];
void update(int x){tree[x].siz=tree[tree[x].l].siz+tree[tree[x].r].siz+1;}
int build(int l,int r,int father){
	if (l>r)return 0;
	int now=++cnt,mid=(l+r)>>1;
	tree[now].fa=father;
	tree[now].val=str[mid];
	tree[now].l=build(l,mid-1,now);
	tree[now].r=build(mid+1,r,now);
	update(now);
	return now;
}
int getson(int x){return tree[tree[x].fa].r==x;}
void rotate(int x){
	int f=tree[x].fa,g=tree[f].fa,son=getson(x);
	if (son==1){//是右儿子,左旋zag 
		tree[f].r=tree[x].l;
		if (tree[f].r)tree[tree[f].r].fa=f;
	}
	else{//是左儿子,右旋zig 
		tree[f].l=tree[x].r;
		if (tree[f].l)tree[tree[f].l].fa=f;
	}
	tree[f].fa=x;
	if (son==1)tree[x].l=f;
	else tree[x].r=f;
	tree[x].fa=g;
	if (g)
		if (tree[g].r==f)tree[g].r=x;
		else tree[g].l=x;
	update(f);
	update(x);
}
void splaying(int x,int goal){
	if (goal==0)root=x;
	while (1){
		int f=tree[x].fa,g=tree[f].fa;
		if (f==goal)break;
		if (g!=goal)
			if (getson(x)==getson(f))rotate(f);
			else rotate(x);
		rotate(x);
	}
	update(x);
}
int getrnk(int x,int rnk){
	if (rnk==tree[tree[x].l].siz+1)return x;
	if (rnk<=tree[tree[x].l].siz)return getrnk(tree[x].l,rnk);
	if (rnk>=tree[tree[x].l].siz+1)return getrnk(tree[x].r,rnk-tree[tree[x].l].siz-1);
}
void ins(int x,int len){
	int now=getrnk(root,x),nxt=getrnk(root,x+1);
	splaying(now,0);
	splaying(nxt,now);
	tree[nxt].l=build(1,len,nxt);
	update(nxt);
	update(now);
}
void del(int l,int r){
	int now=getrnk(root,l),rson=getrnk(root,r+1);
	splaying(now,0);
	splaying(rson,now);
	tree[rson].l=0;
	update(rson);
	update(now);
}
void getmid(int x){
	if (x==0)return ;
	getmid(tree[x].l);
	cout<<tree[x].val;
	getmid(tree[x].r);
}
int main(){
	tree[1].siz=2;tree[1].l=2;//虚拟祖父,防止旋转时越界 
	tree[2].siz=1;tree[2].fa=1;//虚拟父亲
	root=1,cnt=2;//root指向字符串的根 
	int n=read(),pos=1;
	while (n--){
		char opt[10];
		cin>>opt;
		int x;
		if (opt[0]=='I'){
			x=read();
			for (int i=1;i<=x;i++)cin>>str[i];
			ins(pos,x);
		}
		if (opt[0]=='D')x=read(),del(pos,pos+x);
		if (opt[0]=='G'){
			x=read();
			int rnkx=getrnk(root,pos);
			int rnky=getrnk(root,pos+x+1);
			splaying(rnkx,0);
			splaying(rnky,rnkx);
			getmid(tree[rnky].l);
			puts("");
		}
		if (opt[0]=='M')x=read(),pos=x+1;
		if (opt[0]=='P')pos--;
		if (opt[0]=='N')pos++;
	}
	return 0;
}
2023/5/7 12:46
加载中...