简单用法:

#include <ext/rope>
using namespace __gnu_cxx;
int a[1000];
rope<int> x;
rope<int> x(a,a + n);
rope<int> a(x); x->at(10);
x[10];
x->push_back(x) // 在末尾添加x
x->insert(pos,x) // 在pos插入x
x->erase(pos,x) // 从pos开始删除x个
x->replace(pos,x) // 从pos开始换成x
x->substr(pos,x) // 提取pos开始x个

 

例题一:

IOI2012

scrivener

题意

设计支持如下 3 种操作:

1.T x:在文章末尾打下一个小写字母 x。(type 操作) 
2.U x:撤销最后的x 次修改操作。(Undo 操作)

(注意Query 操作并不算修改操作)

3.Q x:询问当前文章中第x 个字母并输出。(Query 操作)

操作数n<=100000 在线算法

clj都说这是道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)的copy历史版本,因为rope的底层是红黑树,所以copy时只需copy根指针。

一键持久化……

 

例题二:

BZOJ 3673: 可持久化并查集 by zky

n个集合 m个操作

操作:

1 a b 合并a,b所在集合

2 k 回到第k次操作之后的状态(查询算作操作)

3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

0<n,m<=2*10^4

分析:直接可持久化并查集的fa数组就可以了。

ACCode:

#include <cstdio>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx; const int maxm = 20010; rope<int> *rp[maxm]; int find(int i,int x)
{
if(rp[i]->at(x) == x) return x;
int f = find(i,rp[i]->at(x));
if(f == rp[i]->at(x)) return f;
rp[i]->replace(x,f);
return rp[i]->at(x);
} inline void merge(int i,int x,int y)
{
x = find(i,x),y = find(i,y);
if(x != y) rp[i]->replace(y,x);
} int a[maxm],lastans; int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i ++) a[i] = i;
rp[0] = new rope<int> (a,a + n + 1);
for(int i = 1;i <= m;i ++)
{
rp[i] = new rope<int> (*rp[i - 1]);
int opt; scanf("%d",&opt);
if(opt == 1)
{
int a,b; scanf("%d%d",&a,&b);
merge(i,a/* ^ lastans*/,b/* ^ lastans*/);
}
else if(opt == 2)
{
int k; scanf("%d",&k);
rp[i] = rp[k/* ^ lastans*/];
}
else
{
int a,b; scanf("%d%d",&a,&b);
printf("%d\n",lastans = (find(i,a/* ^ lastans*/) == find(i,b/* ^ lastans*/)));
}
}
return 0;
}

 

例题三:

AHOI2006文本编辑器editor

题意

设计数据结构支持

插入删除反转字符串

分析:

由于rope的底层实现,insert,erase,get都是logn的

就是翻转不行,不是自己手写的打不了标记啊!!

怎么办?

答:同时维护一正一反两个rope……反转即交换两个子串……Orz……

区间循环位移?简单,拆成多个子串连起来就好了……

区间a变b b变c c变d …… z变a? 呃……维护26个rope?

区间和?滚蛋,那是线段树的活

区间kth?sorry,与数值有关的操作rope一概不支持……

5555 维修数列只能自己写了……

ACCode:

#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;
}

 

 

END

[rope大法好] STL里面的可持久化平衡树--rope的更多相关文章

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

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

  2. C++ STL rope介绍----可持久化平衡树

    大致介绍: rope这个东西,我刚刚知道这玩意,用的不是很多,做个简单的介绍. 官方说明:我是刘邦(我估计你是看不懂的). rope就是一个用可持久化平衡树实现的“重型”string(然而它也可以保存 ...

  3. C++ STL rope 可持久化平衡树 (可持久化数组)

    官方文档好像 GG 了. rope 不属于标准 STL,属于扩展 STL,来自 pb_ds 库 (Policy-Based Data Structures). 基本操作: #include <e ...

  4. 谈c++ pb_ds库(一)rope大法好

    参考资料 1)官方说明 支持 sorry,cena不支持rope 声明 1)头文件 #include<ext/rope> 2)调用命名空间 using namespace __gnu_cx ...

  5. [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)

    Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或 ...

  6. 【LG3835】可持久化平衡树

    [LG3835]可持久化平衡树 题面 洛谷 解法一 参考文章 rope大法好 \(rope\)基本操作: #include<ext/rope> using namespace __gnu_ ...

  7. [cogs2314][HZOI 2015] Persistable Editor - 可持久化平衡树

    [cogs2314][HZOI 2015]Persistable Editor - 可持久化平衡树 题目链接 首先吐槽扯淡几句 [题目描述] 维护一种可持久化的文本编辑器,支持下列操作: 1 p st ...

  8. 可持久化Trie & 可持久化平衡树 专题练习

    [xsy1629]可持久化序列 - 可持久化平衡树 http://www.cnblogs.com/Sdchr/p/6258827.html [bzoj4260]REBXOR - Trie 事实上只是一 ...

  9. [Luogu 3835]【模板】可持久化平衡树

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入x数 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作 ...

随机推荐

  1. php的date()函数判断今天是星期几

    d  月份中的第几天,有前导零的 2 位数字 01 到 31 D  星期中的第几天,文本表示,3 个字母 Mon 到 Sun j  月份中的第几天,没有前导零 1 到 31 l  ("L&q ...

  2. 面向对象 part6 继承

    继承 js实现的是实现继承/也就是继承实际的方法 //主要依赖:原型链 //基本思路: 就是一个引用类型继承另一个引用类型的属性和方法 详细:构造函数,实例,原型之间的关系.每个构造函数都有一个原型对 ...

  3. 第二季第十一天 html5语义化标签 css透明度

    span不能设置宽高背景 HTML5语义化标签 <section>标签所包裹的是有一组相似的主题的内容,可以用这个标签来实现文章的章节.标签式对话框中的各种标签页等类似的功能. <s ...

  4. 1013A.Piles With Stones

    题目出处:http://codeforces.com/contest/1013/problem/A #include<iostream> using namespace std; int ...

  5. 小白学习之pytorch框架(6)-模型选择(K折交叉验证)、欠拟合、过拟合(权重衰减法(=L2范数正则化)、丢弃法)、正向传播、反向传播

    下面要说的基本都是<动手学深度学习>这本花书上的内容,图也采用的书上的 首先说的是训练误差(模型在训练数据集上表现出的误差)和泛化误差(模型在任意一个测试数据集样本上表现出的误差的期望) ...

  6. upstream实现内网网站在公网访问

    背景描述:公司内网有个网站aa.com,B部门需要访问这个aa.com,但是网站部署在内网服务器(服务器是192.168.1网段),B部门网段是192.168.100 需求描述:B部门需要访问aa.c ...

  7. IMX6开发板qt creator直接编译ARM架构程序

    除了通过 11.2.2 小节通过命令行的操作来编译在 iTOP-imx6 开发板上运行的程序,还可以直接在 qtcreator 上设置,然后每次编译的程序都可以在开发板上运行.如下图所示,打开 qtc ...

  8. ElasticSearch 本机可以访问,外网无法访问----问题解决

    问题:本机可以访问,外网无法访问 config/elasticsearch.yml network.host: 0.0.0.0 使用普通用户zuoys,重启es,报错如下: [1]: max file ...

  9. [GX/GZOI2019]旧词(树上差分+树剖+线段树)

    考虑k=1的做法:这是一道原题,我还写过题解,其实挺水的,但当时我菜还是看题解的:https://www.cnblogs.com/hfctf0210/p/10187947.html.其实就是树上差分后 ...

  10. CentOS7离线安装MySQL8.0

    CentOS7离线安装MySQL8.0 卸载软件 rpm -e --nodeps 要卸载的软件包 root@jacky zookeeper]# rpm -e --nodeps java-1.6.0-o ...