2021.07.02 P1383 高级打字机题解(可持久化平衡树)

分析:

从可以不断撤销并且查询不算撤销这一骚操作可以肯定这是要咱建一棵可持久化的树(我也只会建可持久化的树,当然,还有可持久化并查集),正好练习一下可持久化平衡树。

可持久化平衡树:

如果还没学过可持久化平衡树,那就先去学一下吧~

从fhq treap开始:

https://blog.csdn.net/CABI_ZGX/article/details/79963427

[总结] fhq_Treap 学习笔记 - YoungNeal - 博客园 (cnblogs.com)

进入可持久化时代:

题解 P5055 【【模板】可持久化文艺平衡树】 - KevinYu 的博客 - 洛谷博客 (luogu.com.cn)

平衡树练习题:

正常的平衡树:

P3369 【模板】普通平衡树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P3391 【模板】文艺平衡树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

CF702F T-Shirts - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

可持久化平衡树:

P3835 【模板】可持久化平衡树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P5055 【模板】可持久化文艺平衡树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

步入正题:

温馨提示:一定要舍得开空间,把空间开大些。几乎就是版子~

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
const int N=1e5+10;
int n,root[N],cnt,top;
struct node{
	int l,r,size,rd;
	char val;
}t[N<<5];
inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*w;
}
void update(int x){
	t[x].size=t[t[x].l].size+t[t[x].r].size+1;
}
int newnode(char ch){
	++cnt;
	t[cnt].l=t[cnt].r=0;
	t[cnt].size=1;t[cnt].rd=rand();
	t[cnt].val=ch;
	return cnt;
}
int copy(int x){
	++cnt;
	t[cnt]=t[x];
	return cnt;
}
int merge(int x,int y){
	if(!x||!y)return x+y;
	else{
		if(t[x].rd>t[y].rd){
			t[x].r=merge(t[x].r,y);
			update(x);
			return x;
		}else{
			t[y].l=merge(x,t[y].l);
			update(y);
			return y;
		}
	}
}
void split(int rt,int k,int &x,int &y){
	if(!rt)x=y=0;
	else{
		if(t[t[rt].l].size<k){
			x=copy(rt);
			split(t[x].r,k-t[t[rt].l].size-1,t[x].r,y);
			update(x);
		}else{
			y=copy(rt);
			split(t[y].l,k,x,t[y].l);
			update(y);
		}
	}
}
void query(int &rt,int pos){
	int r1,r2,r3;
	split(rt,pos,r1,r3);
	split(r1,pos-1,r1,r2);
	cout<<t[r2].val<<endl;
	rt=merge(merge(r1,r2),r3);
}
void insert(int &rt,int pos,char x,int &rti){
	int r1,r2;
	split(rt,pos,r1,r2);
	int xi=newnode(x);
	rti=merge(merge(r1,xi),r2);
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		string s;
		cin>>s;
		if(s[0]=='T'){
			string x;
			cin>>x;
			int pos=t[root[top]].size,topi=top+1;
			insert(root[top],pos,x[0],root[topi]);
			++top;
		}else if(s[0]=='U'){
			int x;
			cin>>x;
			root[top+1]=root[top-x];
			++top;
		}else if(s[0]=='Q'){
			int x;
			cin>>x;
			query(root[top],x);
		}
	}
	return 0;
}
//7 T A U 1 T B T C Q 2 U 1 Q 1
 posted on 2021-07-02 21:02  eleveni  阅读(63)  评论(0)    收藏  举报