Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3678  Solved: 1380

Description

这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格。光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间。文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程序。如果这段文本为空,我们就说这个文本编辑器是空的。 编写一个程序: 建立一个空的文本编辑器。 从输入文件中读入一些操作指令并执行。 对所有执行过的GET操作,将指定的内容写入输出文件。

Input

输入文件中第一行是指令条数N,以下是需要执行的N个操作。除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。

Output

依次对应输入文件中每条GET指令的输出,不得有任何多余的字符。

Sample Input

10
Insert 13
Balanced eert
Move 2
Delete 5
Next
Insert 7
editor
Move 0
Get
Move 11
Rotate 4
Get

Sample Output

B
t

HINT

对输入数据我们有如下假定: MOVE操作不超过50 000个,INSERT、DELETE和ROTATE操作作的总个数不超过6 000,GET操作不超过20 000个,PREV和NEXT操作的总个数不超过20 000。 所有INSERT插入的字符数之和不超过2M(1M=1 024*1 024)。 DELETE操作、ROTATE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作不会把光标移动到非法位置。 输入文件没有错误。

Source

Splay树

肝过维修数列之后,这文本编辑器还是比较好写的。

总之就是各种模拟操作。

第一遍数组开小了T了,开大数组之后WAWAWA

左看右看找不出错,就试着改读入格式。

调了半个多小时无果,觉得有哪里不对。

好像每输出一个字符是要换行的……说好的“对应输入文件中每条GET指令的输出,不得有任何多余的字符”呢?

加个换行就过了,理论上是2A(强行)

不过改了读入之后,时间从2000ms降到了1700+ms (虽然还是好大)

原代码:

 /*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct node{
int ch[];
bool rev;
int w,fa,size;
}t[mxn];
int a[mxn];
int root,cnt=;
int cpos=;//模拟光标
void pushdown(int x){
if(t[x].rev){
swap(t[x].ch[],t[x].ch[]);
t[t[x].ch[]].rev^=; t[t[x].ch[]].rev^=;
t[x].rev=;
}
return;
}
void pushup(int x){
t[x].size=t[t[x].ch[]].size+t[t[x].ch[]].size+;return;
}
void rotate(int x,int &k){
// printf("rotate:%d %d\n",x,k);
int y=t[x].fa,z=t[y].fa,lc,rc;
if(t[y].ch[]==x)lc=;else lc=; rc=lc^;
if(y==k)k=x;
else t[z].ch[t[z].ch[]==y]=x;
t[x].fa=z;t[y].fa=x;t[t[x].ch[rc]].fa=y;
t[y].ch[lc]=t[x].ch[rc];t[x].ch[rc]=y;
pushup(y);
// pushup(x);
return;
}
void Splay(int x,int &k){
pushdown(x);
while(x!=k){
int y=t[x].fa;int z=t[y].fa;
if(y!=k)
if((t[z].ch[]==y)^(t[y].ch[]==x))rotate(x,k);
else rotate(y,k);
rotate(x,k);
}
pushup(x);
return;
}
int st[mxn],top=; int newnode(int x){
int tmp;
if(top)tmp=st[top--];
else tmp=++cnt;
t[tmp].ch[]=t[tmp].ch[]=;
t[tmp].size=;t[tmp].w=x;
t[tmp].rev=;
return tmp;
}
int Build(int l,int r,int fa){
if(l>r)return ;
int mid=(l+r)>>;
int rt=newnode(a[mid]);
t[rt].ch[]=Build(l,mid-,rt);
t[rt].ch[]=Build(mid+,r,rt);
t[rt].fa=fa;
pushup(rt);
return rt;
}
void split(int x,int y){
Splay(x,root);
Splay(y,t[x].ch[]);
return;
}
int find(int x,int w){
if(t[x].rev)pushdown(x);
// printf("rt:%d lc:%d rc:%d sz:%d %d\n",x,t[x].ch[0],t[x].ch[1],t[x].size,w);
if(w<=t[t[x].ch[]].size)return find(t[x].ch[],w);
if(w==t[t[x].ch[]].size+)return x;
return find(t[x].ch[],w-t[t[x].ch[]].size-);
}
void insert(int pos){
int n=read();
for(int i=;i<=n;i++)
a[i]=getchar();
int tmp=Build(,n,);
int x=find(root,pos),y=find(root,pos+);
split(x,y);
t[y].ch[]=tmp;
t[tmp].fa=y;
pushup(y);pushup(x);
// printf("finished\n");
// for(int i=1;i<=n;i++)printf("%c",a[i]);
// printf("\n");
return;
}
void del(int &x){
if(!x)return;
// printf("del:%d\n",x);
t[t[x].fa].size-=t[x].size;
t[x].fa=;
st[++top]=x;
del(t[x].ch[]);del(t[x].ch[]);
x=;
return;
}
void Dele(int pos,int len){
int x=find(root,pos),y=find(root,pos+len+);
// printf("%d %d\n",x,y);
split(x,y);
del(t[y].ch[]);
return;
}
void reverse(int pos,int len){
int x=find(root,pos),y=find(root,pos+len+);
split(x,y);
t[t[y].ch[]].rev^=;
pushdown(t[y].ch[]);
return;
}
void Debug(int x){
if(t[x].ch[])Debug(t[x].ch[]);
if(t[x].w)printf("%c",t[x].w);
if(t[x].ch[])Debug(t[x].ch[]);
return;
}
void Get(){
// for(int i=0;i<=cnt;i++){
// printf("rt:%d lc:%d rc:%d\n",i,t[i].ch[0],t[i].ch[1]);
// printf("fa:%d sz:%d w:%d\n",t[i].fa,t[i].size,t[i].w);
// printf("\n");
// } int x=find(root,cpos+);
if(t[x].w)printf("%c\n",t[x].w);
else puts(" ");
return;
}
int n;
int main(){
int i,j,x;
int st=,ed=;
n=read();
char op[];
cpos=;
root=Build(,,);
// printf("fin\n");
st=find(root,);
ed=find(root,);
while(n--){
scanf("%s",op);
switch(op[]){
case 'M':{
x=read();
cpos=x+;
break;
}
case 'I':{
insert(cpos);
break;
}
case 'D':{
x=read();
Dele(cpos,x);
break;
}
case 'R':{
x=read();
reverse(cpos,x);
break;
}
case 'G':{Get();break;}
case 'P':{cpos--;break;}
case 'N':{cpos++;break;}
// case 'K':{printf("root:%d\n",root);Debug(root);break;}
}
}
return ;
}

从阿当学长那学到的读入方式:

 /*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mxn=;
struct node{
int ch[];
bool rev;
int w,fa,size;
}t[mxn];
char a[];
int root,cnt=;
int cpos=;//模拟光标
void pushdown(int x){
if(t[x].rev){
swap(t[x].ch[],t[x].ch[]);
t[t[x].ch[]].rev^=; t[t[x].ch[]].rev^=;
t[x].rev=;
}
return;
}
void pushup(int x){
t[x].size=t[t[x].ch[]].size+t[t[x].ch[]].size+;return;
}
void rotate(int x,int &k){
int y=t[x].fa,z=t[y].fa,lc,rc;
if(t[y].ch[]==x)lc=;else lc=; rc=lc^;
if(y==k)k=x;
else t[z].ch[t[z].ch[]==y]=x;
t[x].fa=z;t[y].fa=x;t[t[x].ch[rc]].fa=y;
t[y].ch[lc]=t[x].ch[rc];t[x].ch[rc]=y;
pushup(y);
return;
}
void Splay(int x,int &k){
pushdown(x);
while(x!=k){
int y=t[x].fa;int z=t[y].fa;
if(y!=k)
if((t[z].ch[]==y)^(t[y].ch[]==x))rotate(x,k);
else rotate(y,k);
rotate(x,k);
}
pushup(x);
return;
}
int st[mxn],top=; int newnode(int x){
int tmp;
if(top)tmp=st[top--];
else tmp=++cnt;
t[tmp].ch[]=t[tmp].ch[]=;
t[tmp].size=;t[tmp].w=x;
t[tmp].rev=;
return tmp;
}
int Build(int l,int r,int fa){
if(l>r)return ;
int mid=(l+r)>>;
int rt=newnode(a[mid]);
t[rt].ch[]=Build(l,mid-,rt);
t[rt].ch[]=Build(mid+,r,rt);
t[rt].fa=fa;
pushup(rt);
return rt;
}
void split(int x,int y){
Splay(x,root);
Splay(y,t[x].ch[]);
return;
}
int find(int x,int w){
if(t[x].rev)pushdown(x);
if(w<=t[t[x].ch[]].size)return find(t[x].ch[],w);
if(w==t[t[x].ch[]].size+)return x;
return find(t[x].ch[],w-t[t[x].ch[]].size-);
}
void Debug(int x){
if(t[x].ch[])Debug(t[x].ch[]);
if(t[x].w)printf("%c",t[x].w);
if(t[x].ch[])Debug(t[x].ch[]);
return;
}
void insert(int pos){
int n;scanf("%d%*c",&n);
gets(a+);
int tmp=Build(,n,);
int x=find(root,pos),y=find(root,pos+);
split(x,y);
t[y].ch[]=tmp;
t[tmp].fa=y;
pushup(y);pushup(x);
return;
}
void del(int &x){
if(!x)return;
t[t[x].fa].size-=t[x].size;
t[x].fa=;
st[++top]=x;
del(t[x].ch[]);del(t[x].ch[]);
x=;
return;
}
void Dele(int pos,int len){
int x=find(root,pos),y=find(root,pos+len+);
split(x,y);
del(t[y].ch[]);
return;
}
void reverse(int pos,int len){
int x=find(root,pos),y=find(root,pos+len+);
split(x,y);
t[t[y].ch[]].rev^=;
pushdown(t[y].ch[]);
return;
} void Get(){
int x=find(root,cpos+);
if(t[x].w)printf("%c\n",t[x].w);
else puts(" ");
return;
}
int n;
int main(){
int i,j,x;int st=,ed=;
scanf("%d%*c",&n);
char op[];
cpos=;
a[]=a[]=;
root=Build(,,);
st=find(root,);ed=find(root,);
while(n--){
scanf("%s%*c",op);
switch(op[]){
case 'M':{scanf("%d%*c",&x);cpos=x+;break;}
case 'I':{insert(cpos);break;}
case 'D':{scanf("%d%*c",&x);Dele(cpos,x);break;}
case 'R':{scanf("%d%*c",&x);reverse(cpos,x);break;}
case 'G':{Get();break;}
case 'P':{cpos--;break;}
case 'N':{cpos++;break;}
}
}
return ;
}

Bzoj1269 [AHOI2006]文本编辑器editor的更多相关文章

  1. BZOJ1269 [AHOI2006]文本编辑器editor 【82行splay】

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4633  Solved: 1782 [Sub ...

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

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

  3. [BZOJ1269] [AHOI2006] 文本编辑器editor (splay)

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

  4. BZOJ1269——[AHOI2006]文本编辑器editor

    1.题意:各种splay操作,一道好的模板题2333 2.分析:splay模板题,没啥解释QAQ #include <stack> #include <cstdio> #inc ...

  5. 【rope】bzoj1269 [AHOI2006]文本编辑器editor

    维护一个字符串,支持以下操作:   主要就是 成段插入.成段删除.成段翻转.前两个操作很好通过rope实现.第三个操作也不难,维护两个rope,一个正向,一个反向,翻转时swap一下就行了.   ro ...

  6. 【BZOJ1269/1507】[AHOI2006]文本编辑器editor Splay

    [BZOJ1269][AHOI2006]文本编辑器editor Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目 ...

  7. 【bzoj1507】[NOI2003]Editor /【bzoj1269】[AHOI2006]文本编辑器editor Splay

    [bzoj1507][NOI2003]Editor 题目描述 输入 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中 ...

  8. AHOI2006文本编辑器editor

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1885  Solved: 683[Submit ...

  9. BZOJ 1269: [AHOI2006]文本编辑器editor( splay )

    splay..( BZOJ 1507 题目基本相同..双倍经验 ) ------------------------------------------------------------------ ...

随机推荐

  1. Atitit java集成内嵌浏览器与外嵌浏览器attilax总结

    Atitit java集成内嵌浏览器与外嵌浏览器attilax总结 HTML5将颠覆原生App世界.这听起来有点危言耸听,但若认真分析HTML5的发展史,你会发现,这个世界的发展趋势确实就是这样. 熟 ...

  2. CSS3_01之选择器、Hack

    1.兄弟选择器:①相邻兄弟选择器:元素的后一个兄弟元素,选择器1+选择器2:②通用兄弟选择器:元素后的所有兄弟元素,选择器1~选择器2: 2.属性选择器:attr表示属性名称,elem表示元素名:①[ ...

  3. 小程序https Android 安卓可以发request请求,IOS 苹果 发请求失败问题

    如果一个机器可以发送成功,一个机器发送失败,那多半是是域名的https支持的问题 那就用腾讯云的这个ssl测试工具检测下 https://www.qcloud.com/product/ssl#user ...

  4. (十三)Maven插件解析运行机制

    这里给大家详细说一下Maven的运行机制,让大家不仅知其然,更知其所以然. 1.插件保存在哪里? 与我们所依赖的构件一样,插件也是基于坐标保存在我们的Maven仓库当中的.在用到插件的时候会先从本地仓 ...

  5. AngularJS 系列 01 - HelloWorld和数据绑定

    目录导读: AngularJS 系列 学习笔记 目录篇 前言: 好记性不如烂键盘,随笔就是随手笔记,希望以后有用. 本篇目录: 1. Hello World 2. AngularJS中的数据绑定 3. ...

  6. Sql基础

    SELECT 列名称 FROM 表名称 SELECT * FROM 表名称 SELECT DISTINCT Company FROM Orders 去重 SELECT 列名称 FROM 表名称 WHE ...

  7. [转]How do you create a custom AuthorizeAttribute in ASP.NET Core?

    问: I'm trying to make a custom authorization attribute in ASP.NET Core. In previous versions it was ...

  8. 升级xcode8之后出现报错提示,提示swift版本问题

    最近Xcode升级了,出现了各种蛋疼的错误提示,今天遇到个导入框架出现了提示Swift版本的问题,具体如下: "Use Legacy Swift Language Version" ...

  9. Intellij IDEA 一些不为人知的技巧

    Intellij IDEA 一些不为人知的技巧 2016/12/06 | 分类: 基础技术 | 0 条评论 | 标签: IntelliJ 分享到:38 原文出处: khotyn 今天又听了 Jetbr ...

  10. ssh无密码登录The authenticity of host 'localhost (::1)' can't be established.

    The authenticity of host 'localhost (::1)' can't be established. http://blog.csdn.net/cyuyan112233/a ...