可持久化杀手——rope学习笔记
作者:互联网
概述
std::rope
,内部一说是可持久化平衡树,一说是块状链表。
它可以实现很多可持久化数组问题。
基本使用
#include<bits/extc++.h>
using namespace __gnu_cxx; // 引入rope
rope<char> a; //建立一个存储char的rope
crope a; //crope实际上就是rope<char>
a.push_back('Y'); //在rope尾部新增一个元素
a[1]; // 获得 1 处元素
a.at(1); // 实际上就是 a[1]
rope<char> b=a; // 赋值
我们可以使用rope数组来实现可持久化数组。
P1383 高级打字机
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下 \(3\) 种操作:
1.T x
:在文章末尾打下一个小写字母 \(x\)。(type 操作 )
2.U x
:撤销最后的 \(x\) 次修改操作。(Undo 操作)
(注意 Query 操作并不算修改操作)
Q x
:询问当前文章中第 \(x\) 个字母并输出。(Query 操作)
文章一开始可以视为空串。
对于 \(100\%\) 的数据 \(n \le 100000\);保证 Undo 操作不会撤销 Undo 操作。
这道题正解主席树,当然也可以rope。
代码如下:
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
const int N = 100000;
int cnt=-1,n;
crope *now[N];
char op,ch;int num;
int main(){
cin>>n;
now[++cnt]=new crope();
for(int i=1;i<=n;i++){
cin>>op;
if(op=='T'){
cin>>ch;
cnt++;
now[cnt]=new crope(*now[cnt-1]); //new version
now[cnt]->push_back(ch);
}
if(op=='U'){
cin>>num;
cnt++;
now[cnt]=new crope(*now[cnt-num-1]);
}
if(op=='Q'){
cin>>num;
cout<<now[cnt]->at(num-1)<<'\n';
}
}
return 0;
}
P6166 [IOI2012] scrivener
有些人说李奥纳多是一个对于 Johannes Gutenberg 的崇拜者,Johannes 是一个发明活字印刷的德国铁匠,为了表达尊敬,李奥纳多设计了一台机器被称为小龙虾代书,那是一个非常简单的打字设备。这机器就像一部简单的现代打字机,但只能接受两个指令。一个指令是 输出一个字符,另一个指令是取消最近的指令。小龙虾代书的最大特点就是拥有这个功能强大的取消指令。因为一个取消指令本身也是一个指令,所以也可以被取消。
你的任务是作出此小龙虾代书的程序,一开始并无输出任何文字,然后开始接受使用者输入的一连串指令,并可查询目前输出文字中的特定位置的字符。详细说明如下:
-
TypeLetter(L)
—附加一个小写字母L在输出文字的最后,\(L\) 可以是 \(a,b,\cdots, z\)。 -
UndoCommands(U)
— 取消之前的 \(U\) 个指令,\(U\) 是一个正整数。 -
GetLetter(P)
— 回传在输出文字中位置为 \(P\) 的字符,\(P\) 是一个非负整数。 输出文字中的第一个字符的位置为 \(0\)。 (这个查询并不是一个指令,因此会被取消指令忽略。)
三种操作可以依照任何顺序被呼叫 \(0\) 次或多次以上。
指令 UndoCommands(U)
会依照原本执行的相反顺序来取消前面 \(U\) 个指令: 如果被取消的指令是 TypeLetter(L)
,就会从输出文字最后面移除字母 \(L\)。如果被取消的指令是 UndoCommands(X)
,那么将会依照原本执行的顺序重新执行之前被取消的 \(X\) 个指令。
对于 \(100\%\) 的数据,\(1 \le N \le 10^6\)。参数 \(U\) 保证不会超过前面已经输入的指令数目,而且参数 \(P\) 一定小于输出文字的长度(也就是输出文字的字母数)。
这道题跟上一题差不多。
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
const int N = 1e6+5;
int cnt,q;
crope now[N];
char op,ch;int num;
int main(){
cin>>q;
while(q--){
cin>>op;
if(op=='P'){
cin>>num;
cout<<now[cnt][num]<<'\n';
}
if(op=='T'){
cnt++;
cin>>ch;
now[cnt]=now[cnt-1];
now[cnt].append(ch);
}
if(op=='U'){
cnt++;
cin>>num;
now[cnt]=now[cnt-num-1];
}
}
return 0;
}
标签:cnt,num,int,杀手,笔记,rope,指令,now 来源: https://www.cnblogs.com/zheyuanxie/p/rope-note.html