stl学习(三)crope的用法
转载自http://blog.csdn.net/iamzky/article/details/38348653
曾经我不会写平衡树……于是在STL中乱翻……学到了pb_ds库中的SXBK的斐波那契堆、支持kth的set,和……ext/rope
先发一个官方的 说明 (鸣谢maoxiaohan1999):
http://www.sgi.com/tech/stl/Rope.html
再来例题
IOI2012
scrivener
题意
设计支持如下 3 种操作:
1.T x:在文章末尾打下一个小写字母 x。(type 操作)
2.U x:撤销最后的x 次修改操作。(Undo 操作)
(注意Query 操作并不算修改操作)
3.Q x:询问当前文章中第x 个字母并输出。(Query 操作)
操作数n<=100000 在线算法
clj都说这是道rope傻逼题……
我的rope标程:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int maxn=1e5+10;
rope<char> *his[maxn];
int n;
int d[maxn];
inline int lowbit(int x){
return x&-x;
}
inline void updata(int x){
while(x<=n){
d[x]++;
x+=lowbit(x);
}
}
inline int get(int x){
int res=0;
while(x){
res+=d[x];
x-=lowbit(x);
}return res;
}
inline char getC(){
char ch=getchar();
while(!isalpha(ch))ch=getchar();
return ch;
}
inline int getint(){
int res=0;
char ch,ok=0;
while(ch=getchar()){
if(isdigit(ch)){
res*=10;res+=ch-'0';ok=1;
}else if(ok)break;
}return res;
}
void deb(rope<char> s){
for(int i=0;i<s.length();i++)
cout<<s[i];puts("");
}
int main(){
freopen("type.in","r",stdin);
freopen("type.out","w",stdout);
n=getint();
his[0]=new rope<char>();
for(int i=1;i<=n;i++){
his[i]=new rope<char>(*his[i-1]);
// deb(*his[i]);
char opt=getC();
if(opt=='T'){
char x=getC();
his[i]->push_back(x);
updata(i);
}else
if(opt=='U'){
updata(i);
int x=getint();
int l=1,r=i,mid,now=get(i);
while(l<r){
mid=(l+r)>>1;
if(now-get(mid)>x)
l=mid+1;
else
r=mid;
}
his[i]=his[l-1]; }else
if(opt=='Q'){
int x=getint()-1;
putchar(his[i]->at(x));
putchar('\n');
}
// deb(*his[i]);
}
return 0;
}
可持久化在哪里呢?
his[i]=new rope<char>(*his[i-1]);
就是这一句!它可以实现O(1)的拷贝历史版本,由于rope的底层是平衡树,copy时copy根节点就行了
用它就可以轻松实现可持久化数组
其余操作不用多说
例二
AHOI2006文本编辑器editor
题意
设计数据结构支持
插入删除反转字符串
#include <cstdio>
#include <ext/rope>
#include <iostream>
#include <algorithm>
using namespace std;
using namespace __gnu_cxx;
crope a,b,tmp;
char s[10];
int now,n,len,size;
char str[2000000],rstr[2000000];
int main(){
scanf("%d",&n);
while(n--){
scanf("%s",s);
switch(s[0]){
case 'M':{scanf("%d",&now);break;}
case 'P':{now--;break;}
case 'N':{now++;break;}
case 'G':{putchar(a[now]);putchar('\n');break;}
case 'I':{
scanf("%d",&size);
len=a.length();
for(int i=0;i<size;i++){
do{str[i]=getchar();}
while(str[i]=='\n');
rstr[size-i-1]=str[i];
}
rstr[size]=str[size]='\0';
a.insert(now,str);
b.insert(len-now,rstr);
break;
}
case 'D':{
scanf("%d",&size);
len=a.length();
a.erase(now,size);
b.erase(len-now-size,size);
break;
}
case 'R':{
scanf("%d",&size);
len=a.length();
tmp=a.substr(now,size);
a=a.substr(0,now)+b.substr(len-now-size,size)+a.substr(now+size,len-now-size);
b=b.substr(0,len-now-size)+tmp+b.substr(len-now,now);
break;
}
}
}
return 0;
}
由于rope的底层实现,insert,erase,get都是logn的
就是翻转不行,不是自己手写的打不了标记啊!!
怎么办?
答:同时维护一正一反两个rope……反转即交换两个子串……Orz……
区间循环位移?简单,拆成多个子串连起来就好了……
区间a变b b变c c变d …… z变a? 呃……维护26个rope?
区间和?滚蛋,那是线段树的活
区间kth?sorry,与数值有关的操作rope一概不支持……
5555 维修数列只能自己写了……
最后的Hint:
rope的部分简单操作
| 函数 | 功能 |
| push_back(x) | 在末尾添加x |
| insert(pos,x) | 在pos插入x |
| erase(pos,x) | 从pos开始删除x个 |
| replace(pos,x) | 从pos开始换成x |
| substr(pos,x) | 提取pos开始x个 |
| at(x)/[x] | 访问第x个元素 |
友情提示:cena不支持rope
stl学习(三)crope的用法的更多相关文章
- Dapper学习(三)之其他用法
这里说的其他用法,是指 Async,Buffered,Transaction,Stored Procedure. 1. 首先 dapper支持异步 ExecuteAsync, QueryAsync, ...
- STL学习三:deque容器
1.Deque简介 deque是“double-ended queue”的缩写,和vector一样都是STL的容器,deque是双端数组,而vector是单端的. deque在接口上和vector非常 ...
- 侯捷STL学习(三)--分配器测试
第七节:分配器测试 标准的分配器Allocator,#include<ext/...>都是拓展的 可以用不同的分配器测试同一容器 分配器allocate() & deallocat ...
- STL学习:STL库vector、string、set、map用法
本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...
- 标准模板库(STL)学习探究之vector容器
标准模板库(STL)学习探究之vector容器 C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...
- ###STL学习--迭代器
点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的迭代器. ###stl学习 |--迭代 ...
- 学习AngularJs:Directive指令用法(完整版)
这篇文章主要学习AngularJs:Directive指令用法,内容很全面,感兴趣的小伙伴们可以参考一下 本教程使用AngularJs版本:1.5.3 AngularJs GitHub: http ...
- jQuery学习笔记之Ajax用法详解
这篇文章主要介绍了jQuery学习笔记之Ajax用法,结合实例形式较为详细的分析总结了jQuery中ajax的相关使用技巧,包括ajax请求.载入.处理.传递等,需要的朋友可以参考下 本文实例讲述了j ...
- DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件
DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件 本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...
- STL中的Vector相关用法
STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int> ...
随机推荐
- CoreDataManager-OC版-兼容iOS10以前的版本
头文件: #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> /** CoreData管理器 */ ...
- android bitmap和数据流的互转
Bitmap aa = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); InputStream input ...
- 【代码笔记】iOS-浮点数处理并去掉多余的0
一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. ...
- Windows 7 安装.net framework 4.0 失败,错误HRESULT 0xc8000222解决办法
今天在客服那里发现一个比较奇怪的错误,在客服机子上安装.NET Framework4.0时,出现如下错误:HRESULT 0xc8000222 百度了下原因,原来是win7自动更新造成的.原文网址:h ...
- WPF学习之路(七)应用程序和窗口(续)
窗口的生命周期 WPF中一个Window类代表一个窗口 一个的窗口的生命周期也有好几个阶段: 1.构造器被调用 2.Window.Initialized事件被触发 3.Window.Activated ...
- 组内Linq培训记录
注: 由于该培训是在组内分享,先写成了Word,而word中的代码都以截图方式呈现了,而在博客园不能很方便的粘贴截图进来,所以我用插入代码的方式加进来,如果文中说“如下图”或“如下图代码”,那么就直接 ...
- WEB核心IOC篇
ioc概念的理解:(不是技术是一种设计思想) IOC (控制反转) IoC(Inverse of Control)的字面意思是 控制反转 ,它包括两个内容: 其一是控制 (控制对象的实 ...
- javascript-简单工厂两种实现方式
简单工厂笔记 两种方式: 第一种:通过实例化对象创建 第二种:通过创建一个新对象然后包装增强其属性和功能来实现 差异性:前一种通过类创建的 对象,如果这些类继承同一个父类,他们父类原型上的方法是可以共 ...
- js中同步与异步请求方式
异步请求方式: $.ajax({ url : 'your url', data:{name:value}, cache : false, async : true, type : "POST ...
- CSS3之让背景图片全部显示
起初是在处理一个图片显示的问题, 图片没有有一部分没有显示出来, 之后用到了background-size, 发现有必要总结一下. background-size 首先声明 background-si ...