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> ...
随机推荐
- github-ssh
# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: ...
- SharePoint 2013 场解决方案包含第三方程序集
前言 当我们使用SharePoint 场解决方案的时候,经常会包含第三方的程序集,而第三方的程序集经常会有强签名的问题,如果有强签名可以部署到GAC,没有的话也可以部署到应用程序下. 那么,很多初学者 ...
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q29-Q31)
Question 29 You are designing a SharePoint 2010 intranet site at your company. The accounting depart ...
- xmpp整理笔记:环境的快速配置(附安装包)
现在虽然环信的xmpp框架很火,但是也有一些弊端.环信的框架部分代码不开源,而且收费模式不科学,用户量一直低于免费线则好,一旦超过,收费极高. xmpp感觉还是从xmppFramework框架学起比较 ...
- Android之手机向导以及设置中心模块的开发
当我们使用的新的软件的时候,我们首先需要教用户如何使用我们的软件,当用户学习完使用教程,下次再登录的时候,我们应该直接跳到我们的功能界面,下面我来展示一下我学习视频做的效果图:手机防盗这个功能模块就是 ...
- iOS tableviewcell 分割线 偏移和颜色
改变颜色 [_hotProductsTableView setSeparatorColor : kSeparatorColor]; -(void)viewDidLayoutSubviews { [su ...
- 【代码笔记】iOS-点击cell时候的动画翻转
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...
- iOS 自定义的对象类型的解档和归档
自定义的对象的解档和归档 如果想对自己自定义的类进行解档和归档的话 必须遵循一个协议:NSCoding Student.h 文件 #import <Foundation/Foundation.h ...
- Scrum敏捷项目管理精要
1. 简介: 敏捷项目管理在我们国家起步比较晚,成功运用的项目不多 百分之六十五的敏捷项目用户为scrum 2.互联网时代的特征,雷军的话: 专注,极致,口碑,快(敏捷项目开发就是要快速) 3.敏捷开 ...
- IIS和tomcat共用80端口
IIS和tomcat共用80端口 很多机器都需要同时使用tomcat和iis两个服务器以部署不同的网站,而解决共用80端口的问题也经常遇到,今天实际操作了一回,以下是具体步骤: 实现tomcat和ii ...