https://www.luogu.org/problemnew/show/P3919

看到上面链接中的题时,我在学会可持久化线段树的同时,第一次学会了一个非常屌(cai)的STL大法——rope!!!

这是一个非标准的STL工具,一般情况下要支持c++11或更高才能用(上次去参加APIO时人家毛子评测用的是c++14啊喂!)

正题:

它的头文件是什么:#include<ext/rope> (注:你可以打开devcpp的目录去翻一翻rope这个头文件看看它的操作啊!)

除了头文件以外还需要什么:using namespace __gnu_cxx; (注:正是因为需要使用这种非std的标准命名空间,大部分竞赛才无法支持这个工具)

定义方法:rope<变量类型>变量名称;

  或       crope 变量名称;

  其中crope相当于定义成rope<char>,即定义为string类型

它到底是什么:

  那得看你想听哪种解释了。

  人话解释:超级string

  算法解释:块状链表(即讲链表与数组的优势结合,形成分块思想)

  用途解释:这本来是一个用于快速操作string的工具,却一般被定义成int,然后用作可持久化线段树!

它有哪些操作(重点):

  ●如果你把rope定义为string:

    insert(int pos, string &s, int n) 将字符串s的前n位插入rope的下标pos处,如没有参数n则将字符串s的所有位都插入rope的下标pos处 (补充地址知识:如果你不想从字符串下标为0(即第一个字符)的地址开始取n位,就将你想开始取的地址代入。如s+1表示从字符串下标为1(即第二个字符)的地址开始取n位。int、char等变量类型的数组都适用这种方法来更改数组操作的起始位置。)

  示例代码:

 char a[];
for(int i=;i<;i++) a[i]=i+'';
r.insert(,a+,);
for(int i=;i<;i++) cout<<r.at(i);

    

      append(string &s,int pos,int n) 把字符串s中从下标pos开始的n个字符连接到rope的结尾,如没有参数n则把字符串s中下标pos后的所有字符连接到rope的结尾,如没有参数pos则把整个字符串s连接到rope的结尾(这里已经给你起始位置参数pos了就没必要用上述的取地址方法了哈)

    (insert和append的区别:insert能把字符串插入到rope中间,但append只能把字符串接到结尾)

    substr(int pos, int len) 提取rope的从下标pos开始的len个字符

      at(int x) 访问rope的下标为x的元素

    

    erase(int pos, int num) 从rope的下标pos开始删除num个字符

    copy(int pos, int len, string &s) 从rope的下标pos开始的len个字符用字符串s代替,如果pos后的位数不够就补足

      replace(int pos, string &x);//从rope的下标pos开始替换成字符串x,x的长度为从pos开始替换的位数,如果pos后的位数不够就补足

    以上是常用操作,不常用操作这里就不再赘述。

    ●如果你把rope定义为int(这里只是以int为例):

     insert(int pos, int *s, int n) 将int数组(以下的s都是int数组)s的前n位插入rope的下标pos处,如没有参数n则将数组s的所有位都插入rope的下标pos处

    append(int *s,int pos,int n) 把数组s中从下标pos开始的n个数连接到rope的结尾,如没有参数n则把数组s中下标pos后的所有数连接到rope的结尾,如没有参数pos则把整个数组s连接到rope的结尾

      substr(int pos, int len) 提取rope的从下标pos开始的len个数

    at(int x) 访问rope的下标为x的元素

    

    erase(int pos, int num) 从rope的下标pos开始删除num个数

    copy(int pos, int len, int *s) 从rope的下标pos开始的len个数用数组s代替,如果pos后的位数不够就补足

      replace(int pos, int *x);//从rope的下标pos开始替换成数组x,x的长度为从pos开始替换的位数,如果pos后的位数不够就补足

  示例代码:

r.append();
r.append();
r.append();
r.append();
r=r.substr(,);
for(int i=;i<r.size();i++) printf("%d ",r.at(i));

它有哪些好处:

  时间复杂度:O(n*sqrt(n)),具体原理详见块状链表

  空间复杂度:O(玄学),此处非常神奇,假如用rope存n个整数,它几乎只需要sqrt(n)的块空间加上一些链表指针的微小空间(个人猜测)。比如下面切的这道题就大方地开了100w个rope,每个rope都是一个存了100w个数的版本……我真是震惊了这东西真的这么省空间?

示范切题:以最上面那个链接中的题为例(可持久化线段树模板)

未完待续

最新文章

  1. Redola.Rpc 的一个小目标
  2. kali4.0 下tftpd-hpa服务无法启动的解决方案
  3. C++ CTime COleTime的一些操作技巧
  4. writing concurrent programs
  5. 初见Gnuplot——时间序列的描述
  6. python学习应用笔记(一)
  7. PAT-乙级-1037. 在霍格沃茨找零钱(20)
  8. 【转】Windows环境下Android NDK环境搭建
  9. gulp初涉
  10. 设计师如何为 Android 应用标注尺寸
  11. GIS Tools for Hadoop 详细介绍
  12. WindowsclientC/C++编程规范“建议”——前言
  13. B - 小Y上学记——小Y的玩偶
  14. OC中Foundation框架之NSDictionary、NSMutableDictionary
  15. 201521145048《Java程序设计》第12周学习总结
  16. 关于管理,你可能一直有 3 个误解zz
  17. yii2 緩存
  18. JNI学习小结
  19. LeetCode 496 Next Greater Element I 解题报告
  20. 定制FileField中的上传文件名称

热门文章

  1. python更新mysql数据
  2. 算法竞赛入门经典-1.5.4 Q&amp;A
  3. ABAP CDS ON HANA-(4)ヘッダー行編集
  4. C# 集合之Dictionary详解
  5. Druid时序数据库常见问题及处理方式
  6. 如何删除TFS项目
  7. GDB抓虫之旅(上篇)
  8. Qt 汽车仪表 QWidget
  9. C++学习012友元
  10. Linux-获得命令帮助man