Bzoj1269 [AHOI2006]文本编辑器editor
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
Insert 13
Balanced eert
Move 2
Delete 5
Next
Insert 7
editor
Move 0
Get
Move 11
Rotate 4
Get
Sample Output
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的更多相关文章
- BZOJ1269 [AHOI2006]文本编辑器editor 【82行splay】
1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4633 Solved: 1782 [Sub ...
- [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)
Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或 ...
- [BZOJ1269] [AHOI2006] 文本编辑器editor (splay)
Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或多 ...
- BZOJ1269——[AHOI2006]文本编辑器editor
1.题意:各种splay操作,一道好的模板题2333 2.分析:splay模板题,没啥解释QAQ #include <stack> #include <cstdio> #inc ...
- 【rope】bzoj1269 [AHOI2006]文本编辑器editor
维护一个字符串,支持以下操作: 主要就是 成段插入.成段删除.成段翻转.前两个操作很好通过rope实现.第三个操作也不难,维护两个rope,一个正向,一个反向,翻转时swap一下就行了. ro ...
- 【BZOJ1269/1507】[AHOI2006]文本编辑器editor Splay
[BZOJ1269][AHOI2006]文本编辑器editor Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目 ...
- 【bzoj1507】[NOI2003]Editor /【bzoj1269】[AHOI2006]文本编辑器editor Splay
[bzoj1507][NOI2003]Editor 题目描述 输入 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中 ...
- AHOI2006文本编辑器editor
1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1885 Solved: 683[Submit ...
- BZOJ 1269: [AHOI2006]文本编辑器editor( splay )
splay..( BZOJ 1507 题目基本相同..双倍经验 ) ------------------------------------------------------------------ ...
随机推荐
- datagrid与webAPI的数据交互(ef mvc )
datagride自带分页工具,当使用分页工具的时候,初始化datagride或者带数据提交到API里面时,会以Json对象的形式将数据传递到API控制器里面,当没有过滤条件或者请求参数.和提交参数的 ...
- table 鼠标移上去改变单元格边框颜色。
表格定义了border-collapse:collapse;边框会合并为一个单一的边框.会忽略 border-spacing 和 empty-cells 属性. 用td:hover,显示不全
- css_03之文本、浮动
1.字体属性:①字体格式:font-family:取值:“microsoft yahei”/Arial……:②字体大小:font-size:取值:pt/px:③字体加粗:font-weight:取值: ...
- 大数据下BI产品如何发挥最大价值
看到这个题目,你是否总感觉云里雾里?你是否真正懂什么叫“大数据”?商业智能BI和大数据又有着什么千丝万缕的联系?为什么说商业智能BI能在大数据中发挥价值? 大数据,指的是所涉及的数据资料量规模巨大到无 ...
- ArcEngine数据删除几种方法和性能比较[转]
四个解决方案: 1.IFeatureCursor 游标查询后,遍历删除 2.更新游标删除IFeatureCursor.DeleteFeature() 3.ITable.DeleteSearchedRo ...
- JavaEE开发基础
1 JavaEE简介 Java平台有三个版本,分别是JavaSE(Java Platform, Standard Edition),JavaEE(Java Platform, Enterprise E ...
- mariadb数据库忘记密码如何找回
1.systemctl stop mariadb ==>停止mariadb数据库 2.mysqld_safe --skip-grant-tables & ==>进入单机模式 3.m ...
- Java 消息摘要 散列 MD5 SHA
package xxx.common.util; import java.math.BigInteger; import java.security.MessageDigest; import jav ...
- Spring类型转换 ConversionSerivce Convertor
以String转Date为例: 定义转换器: import java.text.ParseException; import java.util.Date; import org.apach ...
- php 时间倒计时代码 个人写法 有好的想法的欢迎贴出来分享
$now=time(); $secondtime=$end_time-$now;//期限时间减去现在时间 剩余时间 $second=$secondtime % 60;//取余得到秒数 $nowtime ...