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. windows上如何搭建Git Server

    Git在版本控制方面,相比与SVN有更多的灵活性,对于开源的项目,我们可以托管到Github上面,非常方便,但是闭源的项目就会收取昂贵的费用.那么私有项目,如何用Git进行代码版本控制呢?我们可以自己 ...

  2. 【原】tomcat 7 启动报错:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getSessionCookieConfig()Ljavax/servlet/SessionCookieConfig的解决

    现象: tomcat 7 启动报错:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getSessionCookieConfig() ...

  3. 谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo

    前言 前端已经过了单兵作战的时代了,现在一个稍微复杂一点的项目都需要几个人协同开发,一个战略级别的APP的话分工会更细,比如携程: 携程app = 机票频道 + 酒店频道 + 旅游频道 + ..... ...

  4. javascript浏览器检测

    <script type="text/javascript">   /**  * 获取浏览器类型以及版本号  * 支持国产浏览器:猎豹浏览器.搜狗浏览器.傲游浏览器.3 ...

  5. [Android]使用Dagger 2依赖注入 - 自定义Scope(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5095426.html 使用Dagger 2依赖注入 - 自定义 ...

  6. [Android]异步 layout inflation(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5829809.html 异步 layout inflation ...

  7. Android:让WebView支持<input type=”file”…>元素

    最近在做一个活动页面:用户上传一张图片进行缩放.旋转后点击下一步填写内容后生成图片! 做好后经过各种测试是没有问题的,基本没有什么明显BUG,流程都能走通,但是嵌入到APP后,问题就来了! 在IOS上 ...

  8. [MySQL Reference Manual] 18 复制

    18 复制 18 复制 18.1 复制配置 18.1.1 基于Binary Log的数据库复制配置 18.1.2 配置基于Binary log的复制 18.1.2.1 设置复制master的配置 18 ...

  9. SQL Server附加数据库报错:无法打开物理文件,操作系统错误5

    问题描述:      附加数据时,提示无法打开物理文件,操作系统错误5.如下图: 问题原因:可能是文件访问权限方面的问题. 解决方案:找到数据库的mdf和ldf文件,赋予权限即可.如下图: 找到mdf ...

  10. iOS实现渐变色背景(两种方式实现)

    之前做过类似的功能,现在记录一下,来来来... 效果图: 说明=========================== 方法1: 说明:无返回值 用法:直接调用方法.原理是在view的layer层添加. ...