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> ...
随机推荐
- 关于web软件信息安全问题资料的整理(四)
整理出了几点解决方案 1.修护漏洞.对于防护的一方来看,如果先于攻击一方发现Web系统中存在的漏洞,尽早修复它们,就可以防患于未然,获得最低的防护成本.漏洞的修复方式并不是一定要依靠修改网页代码才可以 ...
- An interesting experiment on China’s censorship
This paper presented a very interesting topic. Censorship in China has always drawn people's attenti ...
- [Android]使用RecyclerView替代ListView(二)
以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4242541.html 以前写过一篇“[Android]使用Adapte ...
- android中Post方式发送HTTP请求
Post方式比Get方式要复杂一点,因为该方式需要将请求的参数放在http请求的正文中,所以需要构造请求体. 步骤: 1.构造URL URL url = new URL(PATH); 2.设置连接 H ...
- Android Studio简单设置
IDE外观&行为 修改主题,修改全局字体 修改主题,想用炫酷的深色主题,就改成Darcula吧:字体的话,选一个带中文的,要不然会有很多口口,我这里用Microsoft YaHei UI,很不 ...
- 拓展:使用终端创建、编译、链接OC…
本文介绍一下如何使用Mac OS X自带终端快速创建.编译.链接OC程序. 1.打开终端 顺序:打开Finder——应用程序——实用工具——终端 2.打开需要存放 .m 文件的路径(比如我需要放到桌面 ...
- iOS7 edgesForExtendedLayout -- 解决冲突 / 系统偏移
今天在做UISearchBar,UISearchDisplayController时遇到了一个问题,在点击搜索栏时阴影部分的位置出现偏差 如下图: 始终觉得很奇怪,后面单独做了一个demo,将同样的代 ...
- iOS开发之多线程技术——NSOperation篇
本篇将从四个方面对iOS开发中使用到的NSOperation技术进行讲解: 一.什么是NSOperation 二.我们为什么使用NSOperation 三.在实际开发中如何使用NSOperation ...
- 巧用Xode中的代码块(转)
在我们编码的过程中,总会发现有一些重复的编码工作,可能你会不厌其烦的去copy and paste,但是你有去考虑过怎样解决这样的问题吗?其实现在很多的编程IDE都能帮助我们减少一些编码的任务,提高编 ...
- SVProgressHUD进度条蒙版
GitHub:https://github.com/samvermette/SVProgressHUDSVProgressHUD和MBProgressHUD效果差不多,不过不需要使用协议,同时也不需要 ...