曾经我不会写平衡树……于是在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);}elseif(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;elser=mid;}his[i]=his[l-1];}elseif(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

【Rope大法好】【STL中丧心病狂的可持久化平衡树】相关推荐

  1. c++自带的可持久化平衡树?rope大法好!(超详细解答 + 5道例题讲解,可直接替代可持久化的线段树、并查集、平衡树!)

    整理的算法模板合集: ACM模板 目录 c++自带的可持久化平衡树?rope大法好! 1. 声明 2. 支持操作 char类型的rope int类型的rope 3. 具体的细节 4. "可持 ...

  2. 牛客多校3 C-Shuffle Cards(rope大法解决数组分块)

    Shuffle Cards 链接:https://www.nowcoder.com/acm/contest/141/C 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2 ...

  3. 2020牛客国庆集训派对day8 G-Shuffle Cards(扩展STL容器,rope可持久化平衡树)

    2020牛客国庆集训派对day8 G-Shuffle Cards(扩展STL容器,rope可持久化平衡树) 题目 https://ac.nowcoder.com/acm/contest/7865/G ...

  4. STL中的nth_element()方法的使用

    STL中的nth_element()方法的使用 通过调用nth_element(start, start+n, end) 方法可以使第n大元素处于第n位置(从0开始,其位置是下标为 n的元素),并且比 ...

  5. hdu1027 Ignatius and the Princess II (全排列 amp; STL中的神器)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=1027 Ignatiu ...

  6. 【每日训练】2020/11/9(Splay ?rope大法好!、数论、构造补图)

    整理的算法模板合集: ACM模板 目录 1. 牛客Shuffle Cards 2.CF992B Nastya Studies Informatics 3.CF990D Graph And Its Co ...

  7. C++STL中的unique函数解析

    一.总述 unique函数属于STL中比较常用函数,它的功能是元素去重.即"删除"序列中所有相邻的重复元素(只保留一个).此处的删除,并不是真的删除,而是指重复元素的位置被不重复的 ...

  8. C++ STL中的优先队列(priority_queue)使用

    原文:https://www.cnblogs.com/cielosun/p/5654595.html 今天讲一讲优先队列(priority_queue),实际上,它的本质就是一个heap,我从STL中 ...

  9. STL中的双向队列deque

    1.STL中的双向队列deque deque也是顺序容器的一种,同时也是一个可变长数组.要使用deque,需要包含头文件deque.所有适用于vector的操作都适用于deque. deque和vec ...

最新文章

  1. jenkins构建一个maven项目[五]
  2. Basler相机Pylon4配置VC++6.0
  3. JMM中有哪些方法建立happen-before规则
  4. SAP Spartacus cxFocus增添了refresh Focus功能后的一些考虑
  5. Python中获取当前日期的格式
  6. 【clickhouse】clickhouse源码 Distributed之表select流程
  7. sqlite主键会加速吗_股指分歧中创下3107新高,权重主动下蹲蓄势,后市会加速吗?...
  8. Servlet容器如何处理请求资源路径
  9. 为什么会自动打开Nautilus文件管理器?
  10. Mybatis的xml映射文件,sql的模糊查询的实现(两种方式)占位符拼接,concat关键字
  11. winForm获取内嵌浏览器网页源代码
  12. PGP加密软件使用教程-云安全技术
  13. JDK7升级到JDK8
  14. 安装window10出错:选中的磁盘具有 MBR 分区表。在 EFI 系统上,Windows只能安装到GPT磁盘。
  15. 【从零开始学习Go语言】一.初识Go语言
  16. 蓝桥杯——单片机学习(3——点亮LED灯)
  17. 【天嵌使用教程】嵌入式主板VS2008开发windows C#基本流程
  18. win系统流畅度测试软件,详细教您win10和win7谁更流畅
  19. C++继承和派生笔记
  20. python自动识别简单图片中的文字

热门文章

  1. 冲刺金三银四,自动化软件测试面试宝典合集(含答案)!
  2. 对路径upload访问被拒绝_Asp.net 对路径的访问被拒绝 解决办法(不是文件的一部分)...
  3. 智能计算机的功能有哪些功能,一款好的智能机器人应该具备哪些功能?
  4. C++ | 引用变量
  5. C++自制小游戏:激光收集器v1.1
  6. 强化学习:在表征空间中进行新颖性搜索以实现样本的高效探索
  7. 物联lot是什么意思_产品上的LOT是什么意思?
  8. php青茶什么时候拆,没拆封的茶叶能放几年
  9. matlab遗传算法(例题及代码)
  10. 关于数据流程图,你真的了解吗?