概述

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 操作并不算修改操作)

  1. 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;
}

最新文章

  1. Android数据加密之Aes加密
  2. pip 安装插件慢的解决方法
  3. nginx 参数详解
  4. 将十六进制的颜色字符串转为UIColor
  5. EXT中的iconCls 图标加载
  6. JasperReports+iReport在eclipse中的使用
  7. 类装载器ClassLoader
  8. Android View事件传递机制
  9. 酷Q机器人,QQ机器人使用教程
  10. UIImage 和 UIImageView区别
  11. Mysql获取去重后的总数
  12. Ubuntu下如何解压各类文件
  13. javamail 发送、读取邮件
  14. mysql日志介绍
  15. ModBus通信协议的【Modbus RTU 协议使用汇总】
  16. Pairs Forming LCM LightOJ - 1236 (算术基本定理)
  17. HTML5重力感应小球冲撞动画实现教程
  18. 读书笔记--C陷阱与缺陷(六)
  19. Java Tutorial
  20. Mac与iPhone的使用

热门文章

  1. 虚拟机安装Linux系统的网络配置
  2. git-secret:在 Git 存储库中加密和存储密钥(下)
  3. 齐博x1第四季《模块插件的制作》系列21-公共表单器的参数选项(7)
  4. 蓝桥杯赛前复习C++
  5. 在ubuntu 上安装golang
  6. 【网络】内网穿透方案&amp;FRP内网穿透实战(基础版)
  7. 如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈
  8. Kubernetes_Deployment全解析(无状态的Pod)
  9. winform的TabContorl的TabPage动态添加滚动条
  10. kubernetes笔记-3-快速入门