洛谷 P4008 [NOI2003]文本编辑器 解题报告
P4008 [NOI2003]文本编辑器
题目描述
很久很久以前,\(DOS3.x\)的程序员们开始对 \(EDLIN\) 感到厌倦。于是,人们开始纷纷改用自己写的文本编辑器⋯⋯
多年之后,出于偶然的机会,小明找到了当时的一个编辑软件。进行了一些简单的测试后,小明惊奇地发现:那个软件每秒能够进行上万次编辑操作(当然,你不能手工进行这样的测试) !于是,小明废寝忘食地想做一个同样的东西出来。你能帮助他吗?
为了明确目标,小明对“文本编辑器”做了一个抽象的定义:
文本:由 \(0\) 个或多个 ASCII 码在闭区间\([32,126]\)内的字符构成的序列。
光标:在一段文本中用于指示位置的标记,可以位于文本首部,文本尾部或文本的某两个字符之间。
文本编辑器:由一段文本和该文本中的一个光标组成的,支持如下操作的数据结构。如果这段文本为空,我们就说这个文本编辑器是空的。
| 操作名称 | 输入文件中的格式 | 功能 |
|---|---|---|
| \(MOVE(k)\) | Move k | 将光标移动到第k个字符之后,如果k=0,将光标移到文本开头 |
| \(INSERT(n,s)\) | Insert n s | 在光标处插入长度为n的字符串s,光标位置不变n≥1 |
| \(DELETE(n)\) | Delete n | 删除光标后的n个字符,光标位置不变,n ≥ 1 |
| \(GET(n)\) | Get n | 输出光标后的n个字符,光标位置不变,n ≥ 1 |
| \(PREV()\) | Prev | 光标前移一个字符 |
| \(NEXT()\) | Next | 光标后移一个字符 |
你的任务是:
建立一个空的文本编辑器。
从输入文件中读入一些操作并执行。
对所有执行过的 GET 操作,将指定的内容写入输出文件。
输入输出格式
输入格式:
输入文件 editor.in 的第一行是指令条数 t,以下是需要执行的 t 个操作。其中:
为了使输入文件便于阅读, Insert 操作的字符串中可能会插入一些回车符, 请忽略掉它们(如果难以理解这句话,可以参照样例) 。
除了回车符之外,输入文件的所有字符的 ASCII 码都在闭区间[32, 126]内。且
行尾没有空格。
这里我们有如下假定:
MOVE 操作不超过 50000 个, INSERT 和 DELETE 操作的总个数不超过 4000,
PREV 和 NEXT 操作的总个数不超过 200000。
所有 INSERT 插入的字符数之和不超过 2M(1M=1024*1024 字节) ,正确的输出文件长度不超过 3M 字节。
DELETE 操作和 GET 操作执行时光标后必然有足够的字符。 MOVE 、 PREV 、 NEXT
操作必然不会试图把光标移动到非法位置。
输入文件没有错误。
对 对 C++ 选手的提示:经测试,最大的测试数据使用 fstream 进行输入有可能会比使用进行输入有可能会比使用 stdio 慢约 1 秒。*
输出格式:
输出文件 editor.out 的每行依次对应输入文件中每条 Get 指令的输出。
话说第一次见着这题是要用块状链表来着,今天不知道为什么就拿平衡树水了过去
感觉还是比较卡时间的
所以我们对于插入删除以及输出最好做到\(O(logn+S)\),而不是\(O(lognS)\)
(这里我对插入偷懒了emm
\(n\)为当前树的大小,\(s\)为操作的字符串长度
Code:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define ls ch[now][0]
#define rs ch[now][1]
const int N=1e6+10;
int ch[N][2],typ[N],val[N],siz[N],tot,root,t,pos,cnt,len;
char opt[12];
void updata(int now){siz[now]=siz[ls]+siz[rs]+1;}
void split(int now,int k,int &x,int &y)
{
if(!now) {x=y=0;return;}
if(siz[ls]+1<=k)
x=now,split(rs,k-siz[ls]-1,rs,y);
else if(siz[ls]>=k)
y=now,split(ls,k,x,ls);
updata(now);
}
int Merge(int x,int y)
{
if(!x||!y) return x+y;
if(val[x]<val[y])
{
ch[x][1]=Merge(ch[x][1],y);
updata(x);
return x;
}
else
{
ch[y][0]=Merge(x,ch[y][0]);
updata(y);
return y;
}
}
int New(int asc)
{
val[++tot]=rand(),typ[tot]=asc,siz[tot]=1;
return tot;
}
void Insert(int asc)
{
int x,y;
split(root,pos,x,y);
root=Merge(x,Merge(New(asc),y));
++pos;
}
void extrack()
{
scanf("%d",&cnt);
int x,y,z;
split(root,pos,x,y);
split(y,cnt,z,y);
root=Merge(x,y);
}
void dfs(int now)
{
if(!now) return;
dfs(ls);
printf("%c",typ[now]);
dfs(rs);
}
void out()
{
scanf("%d",&cnt);
int x,y,z;
split(root,pos,x,y);
split(y,cnt,z,y);
dfs(z);printf("\n");
root=Merge(x,Merge(z,y));
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%s",opt);
if(opt[0]=='M') scanf("%d",&pos);
else if(opt[0]=='I')
{
scanf("%d",&len);
char c;int lpos=pos;
while(len--)
{
c=getchar();
while(c<32||c>126||c=='\n') c=getchar();
Insert(c);
}
pos=lpos;
}
else if(opt[0]=='D') extrack();
else if(opt[0]=='G') out();
else if(opt[0]=='P') --pos;
else ++pos;
}
return 0;
}
2018.9.3
洛谷 P4008 [NOI2003]文本编辑器 解题报告的更多相关文章
- 洛谷 P4008 [NOI2003]文本编辑器
先推广一下 求赞 我们考虑这样的一个问题 给你一个序列,要求你支持插入,删除,查询单点值 如果用数组,查询O(1),插入删除最坏O(n) 如果用链表,插入删除O(1),查询最坏O(n) 如果用平衡树- ...
- 洛谷_Cx的故事_解题报告_第四题70
1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h> struct node { long x,y,c; ...
- 洛谷 P2317 [HNOI2005]星际贸易 解题报告
P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...
- 洛谷 P3802 小魔女帕琪 解题报告
P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...
- 洛谷 P2606 [ZJOI2010]排列计数 解题报告
P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...
- 洛谷1303 A*B Problem 解题报告
洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...
- luogu P4008 [NOI2003]文本编辑器 splay 块状链表
LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...
- 洛谷 P4408 逃学的小孩 解题报告
P4408 [NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?&q ...
- 洛谷 P2292 [HNOI2004] L语言 解题报告
P2292 [HNOI2004] L语言 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章\(T\)是由若干小写字母构成.一个单词 ...
随机推荐
- 牛客小白月赛2 D 虚虚实实 【欧拉图】【连通图】
链接:https://www.nowcoder.com/acm/contest/86/D来源:牛客网 题目描述 震为雷,临危不乱,亨通畅达:巽为风,柔顺伸展,厚载万物. 震卦:洊雷,震,君子以恐惧修省 ...
- Hibernate无法提取结果集
原因:表结构错误或 与 映射文件不一致 org.springframework.dao.InvalidDataAccessResourceUsageException: could not extra ...
- 手机丢了怎么办?MZ给你来支招
1致电运营商挂失手机 2致电银行冻结手机网银 3手机绑定支付宝的拨95188挂失 4微信用户登录110.qq.com冻结账号 5修改微博.微信.QQ等密码 6到手机运营商处补手机卡. 一定要记住啊!手 ...
- Wordpress网站中添加百度统计代码
百度统计是流量分析平台,帮助收集网站访问数据,提供流量趋势.来源分析.转化跟踪.页面热力图.访问流等多种统计分析服务,同时与百度搜索.百度推广.云服务无缝结合,为网站的精细化运营决策提供数据支持,进而 ...
- 无法打开物理文件 XXX.mdf“,操作系统错误 5:”5(拒绝访问。)"的解决办法
http://blog.csdn.net/blackfield/article/details/6550499 用T-SQL命令附加数据库时,出现如下异常信息: 无法打开物理文件 XXX.mdf&qu ...
- 关于 cmd 控制台默认代码页编码的几种方法
造成的中文及特殊字符乱码. 第一种:临时性修改编码 使用 chcp 命令,例如 chcp 65001 ,这回将当前代码页变为 utf-8编码,不过这种方式在关闭 cmd 之后会自动失效. 常用的编码及 ...
- ubuntu安装tomcat7
1. 下载apache-tomcat-7.0.64.tar.gz 进入tomcat官网:http://tomcat.apache.org/download-70.cgi下载相应的压缩包: 2. 上传安 ...
- PHP.33-TP框架商城应用实例-后台9-商品相册-修改、删除(AJAX)
商品相册图片删除 当商品删除时,把相册中的图片一并从硬盘和数据库中删除,根据商品id[因为每一张商品相片都会生成三张缩略图,所以删除时要将其缩略图一并删除] //钩子方法_before_delete: ...
- C#学习你需要知道的---(For和Foreach)
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/52577283 作者:car ...
- ElasticSearch学习笔记(三)-- 查询
1. URISearch详解与演示 2. QueryDSL简介 3. 字段类查询简介及match-query 4. 相关性算分 5. match-phrase-query 6. query-strin ...