知识点 - 持久化序列

知识点 - 持久化序列

解决问题类型:

您需要维护一个序列,其中需要提供以下操作:

  1. 插入一个数到序列的第 t 版本使其成为序列的第 k 项,这个数为 x;
  2. 删除序列的第 t 版本的第 k 项;
  3. 查询序列的第 t 版本的第 k 项。

复杂度:

查找结点 O ( l o g N ) O(logN) O(logN)

例题

持久化序列

代码

  1. 持久化 treap
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
#define ptt pair<treap*,treap*>
namespace IO{
    char ss[1<<17],*A=ss,*B=ss;
    inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
    template<class T>inline void Rd(T&x){
        char c;T y=1;while(c=gc(),!isdigit(c)&&c!=-1);x=c-48;
        while(c=gc(),isdigit(c))x=x*10+c-48;x*=y;
    }
    char sr[1<<21],z[20];int C=-1,Z;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    template<class T>inline void Wt(T x){
        if(C>1<<20)Ot();
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='\n';
    }
}
template<class T>inline bool chkmin(T&a,T const&b){return a>b?a=b,true:false;}
template<class T>inline bool chkmax(T&a,T const&b){return a<b?a=b,true:false;}
const int M=300005;
struct treap{
	int val,sz,pri;
	treap *ls,*rs;
	void* operator new(size_t _){
		static treap Pool[M*25],*allc=Pool;
		return allc++;
	}
	void up(){
		sz=1;
		if(ls!=nullptr) sz+=ls->sz;
		if(rs!=nullptr) sz+=rs->sz;
	}
}*root[M];
inline int SZ(treap *p){return p==nullptr?0:p->sz;}
treap *merge(treap *p,treap *q){
	if(p==nullptr) return q;
	if(q==nullptr) return p;
	if(p->pri<q->pri){
		p=new treap(*p);
		p->rs=merge(p->rs,q);
		return p->up(),p;
	}else{
		q=new treap(*q);
		q->ls=merge(p,q->ls);
		return q->up(),q;
	}
}
ptt split(treap *p,int k){
	if(p==nullptr)  return {nullptr,nullptr};
	p=new treap(*p);
	int sz=SZ(p->ls);
	if(sz<k){
		ptt o=split(p->rs,k-sz-1);
		p->rs=o.x,p->up();
		return {p,o.y};
	}else{
		ptt o=split(p->ls,k);
		p->ls=o.y,p->up();
		return {o.x,p};
	}
}
treap* insert(treap *p,int k,int x,int w){
	if(p==nullptr) return new(treap){x,1,w,nullptr,nullptr};
	p=new treap(*p);
	int sz=SZ(p->ls);
	if(w<p->pri){
		ptt o=split(p,k-1);
		*p=(treap){x,1,w,o.x,o.y};
	}else if(sz+1<k) p->rs=insert(p->rs,k-sz-1,x,w);
	else p->ls=insert(p->ls,k,x,w);
	if(p!=nullptr) p->up();
	return p;
}
treap* remove(treap *p,int k){
	int sz=SZ(p->ls);
	p=new treap(*p);
	if(sz+1==k) p=merge(p->ls,p->rs);
	else if(sz<k) p->rs=remove(p->rs,k-sz-1);
	else p->ls=remove(p->ls,k);
	if(p!=nullptr) p->up();
	return p;
}
int kth(treap *p,int k){
	int res;
	while(p!=nullptr){
		int sz=SZ(p->ls);
		if(sz<k) res=p->val,p=p->rs,k-=sz+1;
		else p=p->ls;
	}
	return res;
}
int main(){
	srand(time(NULL));
	int n,i=0;
	IO::Rd(n);
	while(n--){
		int op,k,x,t;
		IO::Rd(op),IO::Rd(t),IO::Rd(k);
		if(op==1) IO::Rd(x),root[++i]=insert(root[t],k,x,rand());
		if(op==2) root[++i]=remove(root[t],k);
		if(op==3) IO::Wt(kth(root[t],k));
	}
	IO::Ot();
	return 0;
}
  1. rope
#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int MaxN(300007);
rope<int> *H[MaxN];
int main()
{
	int K=0,M,k,x,t,opt;
	H[0]=new rope<int>();
	scanf("%d",&M);
	while(M--)
	{
		scanf("%d%d%d",&opt,&t,&k);
		if(opt==1)
		{
			scanf("%d",&x);
			H[++K]=new rope<int>(*H[t]);
			H[K]->insert(k-1,x);
		}
		if(opt==2)
		{
			H[++K]=new rope<int>(*H[t]);
			H[K]->erase(k-1,1);
		}
		if(opt==3) printf("%d\n",H[t]->at(k-1));
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Best KeyBoard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值