主席树 50pts /dk 一关注
查看原帖
主席树 50pts /dk 一关注
398190
lanretE楼主2023/4/1 22:04
#include<iostream>
using namespace std;
const int N=2e6+10;
int n,m,tot=1,a[N],rt[N];//rt[i]表示第i个根节点在t数组里面的编号 
struct node{
	int l,r;
	char v; 
}t[N<<2];
int new_node(int p){
	t[++tot]=t[p];//把节点p的信息全部复制给新节点 
	return tot;
}
int cnt;
int Change(int p,int l,int r,int x,char v){
	p=new_node(p);//每向下一层建一个点,如果之后的更新不经过右儿子,右儿子会连向原来的,左儿子先是连向原来的但是到下一层的时候会被更新 
	if(l==r) t[p].v=v;
	else{
		int mid=l+r>>1;
		if(x<=mid) t[p].l=Change(t[p].l,l,mid,x,v);
		else t[p].r=Change(t[p].r,mid+1,r,x,v);
	}
	return p;//不管怎么样都要返回当前节点编号 
}
char Query(int p,int l,int r,int x){
	if(l==r){
//		cout<<1;
		return t[p].v;
	} 
	int mid=l+r>>1;
	if(x<=mid) return Query(t[p].l,l,mid,x);
	else return Query(t[p].r,mid+1,r,x);
}
int main(){
	cin>>m;
	int idx=0;
	for(int i=1;i<=m;++i){
		char op,c; int x; cin>>op;
		if(op=='T'){
			cin>>c;
			++idx,++cnt;//cnt表示现有字母数
			rt[idx]=Change(rt[idx-1],1,m,cnt,c);//新建版本,rt[i]就是这个版本根节点的编号 
		}
		else if(op=='U'){
			cin>>x;
			++idx,cnt-=x;
			rt[idx]=rt[idx-x-1];
		}
		else{
			cin>>x; 
			printf("%c\n",Query(rt[idx],1,m,x));
			rt[i]=rt[idx];//查询操作版本不变 
		}
	}
	return 0;
}
2023/4/1 22:04
加载中...