1507: [NOI2003]Editor

Time Limit: 5 Sec  Memory Limit: 162 MB
Submit: 3397  Solved: 1360
[Submit][Status][Discuss]

Description

Input

输入文件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秒。

Output

输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。

Sample Input

15
Insert 26
abcdefghijklmnop
qrstuv wxy
Move 15
Delete 11
Move 5
Insert 1
^
Next
Insert 1
_
Next
Next
Insert 4
.\/.
Get 4
Prev
Insert 1
^
Move 0
Get 22

Sample Output

.\/.
abcde^_^f.\/.ghijklmno

HINT

Source

Solution

有块状链表和平衡树两种做法。

这里用来练块状链表。

Insert和Delete操作都是现将起始两块分裂,然后加入/拿掉中间的块

注意在Insert和Delete操作后要进行一次合并,防止退化成普通链表。

这题数据范围可能比较大,考虑写个内存池

这题把块的大小控制在3500大概能跑到640ms...

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
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;
}
#define MAXN 2000010
#define Bsize 3500
#define Bnum MAXN/Bsize*3
char S[MAXN];
int loc;
namespace BlockLists
{
struct BlockListsNode{char data[Bsize+]; int size,next; }B[Bnum+];
int sz,start;
queue<int>trash;
inline int New() {if (trash.empty()) return ++sz; int tmp=trash.front(); trash.pop(); return tmp;}
inline void Del(int x) {trash.push(x);}
inline int GetP(int rk) {for (int i=start; ~i; i=B[i].next) if (rk>B[i].size) rk-=B[i].size; else return i;}
inline int GetK(int rk) {for (int i=start; ~i; i=B[i].next) if (rk>B[i].size) rk-=B[i].size; else return rk;}
inline void Data(int pos,int len,char data[],int suf) {B[pos].next=suf; B[pos].size=len; memcpy(B[pos].data,data,len);}
inline void Split(int pos,int rk)
{
if (B[pos].size==rk) return;
int id=New(); Data(id,B[pos].size-rk,B[pos].data+rk,B[pos].next); B[pos].next=id; B[pos].size=rk;
}
inline void Merge(int pos)
{
for ( ; ~pos; pos=B[pos].next)
for (int suf=B[pos].next; ~suf && B[pos].size+B[suf].size<Bsize; suf=B[suf].next)
memcpy(B[pos].data+B[pos].size,B[suf].data,B[suf].size),B[pos].size+=B[suf].size,B[pos].next=B[suf].next,Del(suf);
}
inline void Insert(int s,int len)
{
int now=GetP(s),pos=GetK(s),l,id; Split(now,pos);
for (l=; l+Bsize<=len; l+=Bsize)
id=New(),Data(id,Bsize,S+l,B[now].next),B[now].next=id,now=id;
if (l<len) id=New(),Data(id,len-l,S+l,B[now].next),B[now].next=id;
Merge(now);
}
inline void Delete(int s,int len)
{
int now=GetP(s),pos=GetK(s),p; Split(now,pos);
for (p=B[now].next; ~p; p=B[p].next) if (len>B[p].size) len-=B[p].size; else break;
Split(p,len); p=B[p].next;
for (int i=B[now].next; i!=p && ~i; i=B[now].next) B[now].next=B[i].next,Del(i);
Merge(now);
}
inline void GetAns(int s,int len)
{
int now=GetP(s),pos=GetK(s),p,l; l=min(len,B[now].size-pos);
memcpy(S,B[now].data+pos,l);
for (p=B[now].next; ~p && l+B[p].size<=len; p=B[p].next)
memcpy(S+l,B[p].data,B[p].size),l+=B[p].size;
if (l<len && ~p) memcpy(S+l,B[p].data,len-l);
S[len]=; puts(S);
}
inline void Init() {start=,B[].size=,B[].next=-;}
}
using namespace BlockLists;
inline void GetS(int len) {int l=-; while (l<len-) {S[++l]=getchar(); if (S[l]< || S[l]>) l--;}}
int main()
{
// freopen("editor2003.in","r",stdin);
// freopen("editor2003.out","w",stdout);
int T=read();
BlockLists::Init();
while (T--)
{
char opt[]; scanf("%s",opt); int x;
switch (opt[])
{
case 'M': loc=read(); break;
case 'I': x=read(); GetS(x); BlockLists::Insert(loc,x); break;
case 'D': x=read(); BlockLists::Delete(loc,x); break;
case 'G': x=read(); BlockLists::GetAns(loc,x); break;
case 'P': loc--; break;
case 'N': loc++; break;
}
}
return ;
}

说起来太容易了,

昨晚接近3个小时手写模板,然后各种问题...最后还是借鉴了    将狼踩尽    大神的模板

【BZOJ-1507】Editor 块状链表的更多相关文章

  1. 【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor 块状链表模板题

    2016-06-18 当时关于块状链表的想法是错误的,之前维护的是一个动态的$\sqrt{n}$,所以常数巨大,今天才知道原因TwT,请不要参照这个程序为模板!!! 模板题水啊水~~~ 第一次写块状链 ...

  2. BZOJ 1507 Editor(块状链表)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1507 题意:一个文本编辑器,模拟以下操作: 思路:块状链表的主要操作: (1)find( ...

  3. BZOJ 3217: ALOEXT (块状链表套trie)

    第一次写块状链表,发现还挺好写的,但是一点地方写错加上强制在线就会各种姿势WA/TLE/RE爆- 想法就是分块后,在每一个块上维护最大值和次大值,还在每一个块上维护一棵trie树来求异或最大值.散块直 ...

  4. BZOJ 1507 Editor

    Description Input 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它 ...

  5. BZOJ 4864: [BeiJing 2017 Wc]神秘物质 (块状链表/平衡树 )

    这就是一道数据结构裸题啊,最大极差就是区间最大值减最小值,最小极差就是相邻两个数差的最小值.然后平衡树splay/treap或者块状链表维护就行了. 第一次自己写块状链表,蛮好写,就是长..然后就BZ ...

  6. bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)

    [题意] 回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]. [思路] 考虑使用块状链表实现莫队算法中的插入与删除. 因为权值处于1..n之间,所以我们可以建一个基 ...

  7. 洛谷.4008.[NOI2003]editor文本编辑器(块状链表)

    题目链接 st(n)表示sqrt(n) 为使块状链表不会退化,通常将每块的大小S维持在[st(n)/2,2st(n)]中,这样块数C也一定[st(n)/2,2st(n)]中 在此使用另一种方法(方便) ...

  8. [NOI2003]Editor(块状链表)

    传送门 看了看块状链表,就是数组和链表的合体. 看上去好高大尚,思想也很简单. 但是发现代码量也不是很小,而且代码理解起来也是费尽得很,倒不如splay用起来顺手. 在加上适用范围貌似不是特别广,所以 ...

  9. 块状链表 bzoj 3343教主的魔法

    //块状链表//分块排序,然后每次查找时在暴力查找头和尾两个块.//中间那些块,因为有序所以只需2分查找即可.我用的是lower_pound();//插入是,也是头和尾暴力插入,中间那些加到一个累计里 ...

随机推荐

  1. PHP用户注册邮箱验证激活帐号

    我们在很多网站注册会员时,注册完成后,系统会自动向用户的邮箱发送一封邮件,这封邮件的内容就是一个URL链接,用户需要点击打开这个链接才能激活之前在该网站注册的帐号.激活成功后才能正常使用会员功能. 本 ...

  2. linux基本工具使用(二)

    1 查找某个目录下面一个所有的可执行文件,并且删除(对删除一个工程的可执行文件格外有用) find . -maxdepth 1 -file f -perm -111 | xargs rm

  3. [py]shell着色

    print "\033[32;1myou are 30 older and little than 40\033[0m"

  4. 傻瓜看完都可以简单使用Git

    作为当下最流行的版本控制系统,Git是一个分布式版本控制系统,跟SVN等集中式版本控制有很多使用上的不同.万事开头难,想要最快学会使用Git,最简单的就是下了客户端就直接去用,一边用一边学.本文手把手 ...

  5. tkinter 类继承的三种方式

    tkinter class继承有三种方式. 提醒注意这几种继承的运行方式 一.继承 object 1.铺tk.Frame给parent: 说明: self.rootframe = tk.Frame(p ...

  6. 跟我学习Storm_Storm基本概念

    首先我们通过一个Storm和Hadoop的对比来了解Storm中的基本概念. 接下来我们再来具体看一下这些概念. Nimbus:负责资源分配和任务调度. Supervisor:负责接受nimbus分配 ...

  7. Oracle 常用操作【01】修改、更新数据

    1. oracle 修改表名.列名.字段类型.添加表列.删除表列  alert table scott.test rename to test1--修改表名 alter table scott.tes ...

  8. PRML读书会第十一章 Sampling Methods(MCMC, Markov Chain Monte Carlo,细致平稳条件,Metropolis-Hastings,Gibbs Sampling,Slice Sampling,Hamiltonian MCMC)

    主讲人 网络上的尼采 (新浪微博: @Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:05:00  今天的主要内容:Markov Chain Monte Carlo,M ...

  9. 使用spring boot和thrift、zookeeper建立微服务

    Spring cloud适应于云端服务,也适用于企业信息化SOA建设.spring boot也是restful微服务开发的利器.但对于内网服务,即服务与服务之间的调用,spring并没有去刻意封装,也 ...

  10. snr ber Eb/N0之间的区别与联系

    信噪比(S/N)是指传输信号的平均功率与加性噪声的平均功率之比,载噪比(C/N)指已经调制的信号的平均功率与加性噪声的平均功率之比,它们都以对数的方式来计算,单位为dB. 对同一个传输系统而言,载噪比 ...