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. Delphi项目构成之单元文件PAS

    单元文件是Pascal源文件,扩展名为.pas. 有三种类型的单元文件: 窗体/数据模块和框架的单元文件(form/data module and frame units),一般由Delphi自动生成 ...

  2. windows和ubuntu下gif动态图片的制作

    现在社交软件中, 各种各样的动图为大家交流很大的乐趣.  Gif图片比视频小, 比静态JPG图片形象生动, 更适用于产品展示和步骤演示等. 这里简单介绍一下在window系统和ubuntu系统下gif ...

  3. facebook graphql

    思想先进,前端直接从后台调用所需要的数据. 最简单的理解: 从"select * from 学生表" 进化为"select name, sex from 学生表" ...

  4. [转]Linux后台进程管理利器:supervisor

    FROM : http://www.liaoxuefeng.com/article/0013738926914703df5e93589a14c19807f0e285194fe84000 Linux后台 ...

  5. 【转】浅析Sql Server参数化查询

    转载至: http://www.cnblogs.com/lzrabbit/archive/2012/04/21/2460978.html 错误认识1.不需要防止sql注入的地方无需参数化 参数化查询就 ...

  6. java:如何让程序按要求自行重启?

    正文开始前的废话: 这里的程序即包括b/s的web application,也包括standalone的类c/s的java application.   为什么要自我重启?   场景1:分布式环境中, ...

  7. Webwork 学习之路【07】文件上传下载

    Web上传和下载应该是很普遍的一个需求,无论是小型网站还是大并发访问的交易网站.WebWork 当然也提供了很友好的拦截器来实现对文件的上传,让我们可以专注与业务逻辑的设计和实现,在实现上传和下载时顺 ...

  8. C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

  9. java并发:同步容器&并发容器

    第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...

  10. ASP.NET MVC3入门教程之参数(数据)传递

    本文转载自:http://www.youarebug.com/forum.php?mod=viewthread&tid=98&extra=page%3D1 MVC模式的参数(数据)传递 ...