可持久化treap
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
=== stl: rope ===
{{{
#include <cstdio>
#include <iostream>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
crope t,tp[50001],tmp; int po;
char s[101];
int sub;
int main(){
int n; scanf("%d",&n);
for (int d,p,v,c;n--;)
{
scanf("%d",&d);
if (d==1)
{
scanf("%d%s",&p,s);
p-=sub;
t.insert(p,s);//在第p个字符前插入s
tp[++po]=t;
}
else if (d==2)
{
scanf("%d%d",&p,&c);
p-=sub,c-=sub;
t.erase(p-1,c);//删掉p位置开始的c个字符(包括)
tp[++po]=t;
}
else
{
scanf("%d%d%d",&v,&p,&c);
v-=sub,p-=sub,c-=sub;
tmp=tp[v].substr(p-1,c);//返回p位置开始的c个字符(包括)
sub+=count(tmp.begin(),tmp.end(),'c');//计算有多少个字符'c'
cout<<tmp<<endl;
}
}
return 0;
}
//注:上述代码中erase和substr中p的范围都是[1,len],所以要减1
}}}
stl: rope
#include <cstdio>
#include <iostream>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
crope t,tp[50001],tmp; int po;
char s[101];
int sub;
int main(){
int n; scanf("%d",&n);
for (int d,p,v,c;n--;)
{
scanf("%d",&d);
if (d==1)
{
scanf("%d%s",&p,s);
p-=sub;
t.insert(p,s);//在第p个字符前插入s
tp[++po]=t;
}
else if (d==2)
{
scanf("%d%d",&p,&c);
p-=sub,c-=sub;
t.erase(p-1,c);//删掉p位置开始的c个字符(包括)
tp[++po]=t;
}
else
{
scanf("%d%d%d",&v,&p,&c);
v-=sub,p-=sub,c-=sub;
tmp=tp[v].substr(p-1,c);//返回p位置开始的c个字符(包括)
sub+=count(tmp.begin(),tmp.end(),'c');//计算有多少个字符'c'
cout<<tmp<<endl;
}
}
return 0;
}
//注:上述代码中erase和substr中p的范围都是[1,len],所以要减1