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

题目链接

首先吐槽扯淡几句

【题目描述】

维护一种可持久化的文本编辑器,支持下列操作:

1 p str 在当前版本的第p个字符后插入字符串str,并作为下一版本(数据保证0<=p<=当前字符串的长度,且插入的字符串中只有小写字母)

2 p c 在当前版本中删除从第p个字符开始的后c个字符,并作为下一版本(包含第p个字符,数据保证1<=p<=当前字符串的长度,且p+c-1<=当前字符串的长度)

3 x p c 输出第x个版本从第p个字符开始的后c个字符(包含第p个字符,数据保证1<=p<=第x个版本的字符串的长度,且p+c-1<=第x个版本的字符串的长度)

为了体现在线,你需要维护一个变量d,在3操作之后,d加上你输出字符串中字符'c'的数量,并且在数据中给出的操作1中的p,操作2中的p和c,操作3中的x,p,c均为加上变量d的结果,你需要把它们减去d之后运算

开始时为空串,d=0,且为版本0,每进行操作1,2就会以上一版本的基础上修改形成下一版本

【输入格式】

第一行一个数n,表示有n个操作

下面n行,第一个数字为op,表示操作类型

op=1时表示第一种操作,后面有一个数p和一个字符串str,意义同上面的描述,在操作之前,你需要将p减去d,才能得到正确的p,d的意义同上面的描述,表示你之前第三种操作输出的所有字符串中字符'c'的数量

op=2时表示第二种操作,后面有两个数p,c,意义同上面的描述,在操作之前,你需要将p和c减去d,才能得到正确的p和c,d的意义同上面的描述,表示你之前第三种操作输出的所有字符串中字符'c'的数量

op=3时表示第三种操作,后面有三个数x,p,c,意义同上面的描述,在操作之前,你需要将x,p和c减去d,才能得到正确的x,p和c,d的意义同上面的描述,表示你之前第三种操作输出的所有字符串中字符'c'的数量

【输出格式】

对于每个第三种操作输出一行表示结果

【样例输入】

6
1 0 abcdefgh
2 4 3
3 1 2 5
3 3 3 4
1 4 xy
3 5 4 6

【样例输出】

bcdef
bcg
bxyc

【提示】

对于样例解密的结果为

6
1 0 abcdefgh
2 4 3
3 1 2 5
3 2 2 3
1 2 xy
3 3 2 4

本题共20组测试数据,一个点5分,给出数据特征如下

被我吞啦

【来源】

by stdafx

ps:题目异常丑陋,凑合看吧,我只是想普及下rope和可持久化平衡树

pps:数据真难造,比标算还难写

题解

可持久化平衡树。。。看了XXX博客然后1A了并不感动。。。

其实还好啊。。。。

就是每次修改到一个节点时先复制一份副本。。。

il vd copy(point&a,point b){
if(b==null)a=null;
else a=new node('%'),*a=*b;
}

所以修改一下split和merge。。。

il vd merge(point&rt,point a,point b){
if(a==null)copy(rt,b);
else if(b==null)copy(rt,a);
else if(a->rand<b->rand)copy(rt,a),merge(rt->rs,a->rs,b),rt->reset();
else copy(rt,b),merge(rt->ls,a,b->ls),rt->reset();
}
il vd split(point rt,point&a,point&b,int num){
if(!num)copy(b,rt),a=null;
else if(rt->size<=num)copy(a,rt),b=null;
else if(num<=rt->ls->size)copy(b,rt),split(rt->ls,a,b->ls,num),b->reset();
else copy(a,rt),split(rt->rs,a->rs,b,num-rt->ls->size-1),a->reset();
}

然后弄一个root数组记录所有的树根。。。

剩下的和普通平衡树一毛一样。。。

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cstring>
#define Fname "persistable_editor"
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int d=0,cnt=0,seed=151806;
il int Rand(){return seed=seed*19260817ll%2147483647;}
typedef struct node* point;
point null;
struct node{
char data;
int rand,size;
point ls,rs;
node(char _data){data=_data,rand=Rand(),size=1,ls=rs=null;}
il vd reset(){size=ls->size+rs->size+1;}
};
point root[100101];
il vd copy(point&a,point b){
if(b==null)a=null;
else a=new node('%'),*a=*b;
}
il vd merge(point&rt,point a,point b){
if(a==null)copy(rt,b);
else if(b==null)copy(rt,a);
else if(a->rand<b->rand)copy(rt,a),merge(rt->rs,a->rs,b),rt->reset();
else copy(rt,b),merge(rt->ls,a,b->ls),rt->reset();
}
il vd split(point rt,point&a,point&b,int num){
if(!num)copy(b,rt),a=null;
else if(rt->size<=num)copy(a,rt),b=null;
else if(num<=rt->ls->size)copy(b,rt),split(rt->ls,a,b->ls,num),b->reset();
else copy(a,rt),split(rt->rs,a->rs,b,num-rt->ls->size-1),a->reset();
}
il point build(){
char s[203];
scanf("%s",s+1);
int n=strlen(s+1);
point stack[n+2];int top=0;
rep(i,1,n){
point now=new node(s[i]),last=null;
while(top&&stack[top]->rand>now->rand)last=stack[top],stack[top--]->reset();
if(top)stack[top]->rs=now;now->ls=last,stack[++top]=now;
}
while(top)stack[top--]->reset();
return stack[1];
}
il vd ins(){
int p=gi()-d;
point a,b;
split(root[cnt],a,b,p);
merge(a,a,build()),merge(root[++cnt],a,b);
}
il vd del(){
int p=gi()-d,tot=gi()-d;
point a,b,c;
split(root[cnt],a,b,p-1),split(b,b,c,tot);
merge(root[++cnt],a,c);
}
il vd dfs(point now){
if(now->data=='c')++d;
if(now!=null)dfs(now->ls),putchar(now->data),dfs(now->rs);
}
il vd prt(){
int x=gi()-d,p=gi()-d,tot=gi()-d;
point a,b,c;
split(root[x],a,b,p-1),split(b,b,c,tot);
dfs(b),puts("");
merge(a,a,b),merge(root[x],a,c);
}
int main(){
freopen(Fname".in","r",stdin);
freopen(Fname".out","w",stdout);
int n=gi(),opt;
null=new node('%');
null->size=0;
rep(i,0,n)root[i]=null;
while(n--){
opt=gi();
if(opt==1)ins();
if(opt==2)del();
if(opt==3)prt();
}
return 0;
}

所以我1A了好感动。。。

最后扯淡几句

我竟然上榜了。。。

[cogs2314][HZOI 2015] Persistable Editor - 可持久化平衡树的更多相关文章

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

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

  2. BZOJ 2287. [HZOI 2015]疯狂的机器人 [FFT 组合计数]

    2287. [HZOI 2015]疯狂的机器人 题意:从原点出发,走n次,每次上下左右不动,只能在第一象限,最后回到原点方案数 这不煞笔提,组合数写出来发现卷积NTT,然后没考虑第一象限gg 其实就是 ...

  3. Bitset([HZOI 2015]偏序++)

    Bitset简介 下面介绍C++ STL 中一个非常有用的东西: Bitset 类似于二进制状压,它可以把信息转化成一个01串存储起来 定义方法: 首先要#include<bitset>或 ...

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

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

  5. 洛谷P3835 【模板】可持久化平衡树

    题目背景 本题为题目 普通平衡树 的可持久化加强版. 数据已经经过强化 感谢@Kelin 提供的一组hack数据 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作( ...

  6. P3835 【模板】可持久化平衡树

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

  7. 【COGS】2287:[HZOI 2015]疯狂的机器人 FFT+卡特兰数+排列组合

    [题意][COGS 2287][HZOI 2015]疯狂的机器人 [算法]FFT+卡特兰数+排列组合 [题解]先考虑一维的情况,支持+1和-1,前缀和不能为负数,就是卡特兰数的形式. 设C(n)表示第 ...

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

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

  9. LG3835 【模板】可持久化平衡树

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

随机推荐

  1. 人人开源之renren-security

    renren-security,从这周开始我将要对其比较详细的研究,之前的研究只不过是比较浅的.正如在这篇文章读读<编写高质量代码:改善Java程序的151条建议>中说过不要重复造轮子. ...

  2. EF Core 2.1 支持数据库一对一关系

    在使用EF Core和设计数据库的时候,通常一对多.多对多关系使用得比较多,但是一对一关系使用得就比较少了.最近我发现实际上EF Core很好地支持了数据库的一对一关系. 数据库 我们先来看看SQL ...

  3. 转 Grand Central Dispatch 基础教程:Part 1/2 -swift

    本文转载,原文地址:http://www.cocoachina.com/ios/20150609/12072.html 原文 Grand Central Dispatch Tutorail for S ...

  4. 关于如何解决bootstrap table 列 切换 刷新 高度不一样

    在使用bootstrap table时候,碰到bootstrap table 列 切换 刷新 高度不一样的问题,如图所示: 解决这个问题很简单,在你的页头加一句<!DOCTYPE html> ...

  5. Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介

    约定 还记得上版本的第二十四篇的约定嘛?现在出来履行啦~ 为什么要重制? 之前写的专栏都是按照心情写的,在最初的时候笔者什么都不懂,而且文章的发布是按照很随性的一个顺序.结果就是说,大家都看完了,都还 ...

  6. 实际SQL案例解决方法整理_LEAD函数相关

    表结构及数据如下: 需求: 将记录按照时间顺序排列,每三条记录为一组,若第二条记录与第一条记录相差5分钟,则删除该记录,若第三条与第二条记录相差5分钟,则删除该记录, 第二组同理,遍历全表,按要求删除 ...

  7. Xcode缓存数据清除

    1. 移除 APP 打包的ipa历史版本(Archives) 不可恢复,就是你打的包,如果需要dysm文件,及时备份 路径:~/Library/Developer/Xcode/Archives 2. ...

  8. Linux基础命令之关机,重启,注销

    shutdown 此命令用来安全关闭或重启Linux系统,系统在关闭之前会通知所有的登录用户,系统即将关闭,此时所有新用户都不可以登录. 以下截取man手册的内容(man shutdown): NAM ...

  9. 每天一个linux命令(1):find命令之exec

    ind是我们很常用的一个Linux命令,但是我们一般查找出来的并不仅仅是看看而已,还会有进一步的操作,这个时候exec的作用就显现出来了. exec解释:-exec 参数后面跟的是command命令, ...

  10. rpm与yum,at与crontab,sed命令使用

    1.简述rpm与yum命令的常见选项,并举例. rpm——软件包管理系统,它使得在Linux下安装.升级.删除软件包的工作变得容易,并且具有查询.验证软件包的功能. 1)安装选项 命令格式: rpm ...