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. BZOJ 1588: [HNOI2002]营业额统计

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 14396  Solved: 5521[Submit][Sta ...

  2. 临时表之IF-ELSE

    1.解决输出单列到临时表 场景:存储过程传入id,id为缺省的过滤条件,如果id为0,则查找出tt表中的所有id作为过滤条件 目的:id不为0时,过滤id 解决:用case when来代替if els ...

  3. iptables案例手册

    Linux防火墙Iptable如何设置只允许某个ip访问80端口,只允许特定ip访问某端口 iptables常用实例备查(更新中) 9个常用iptables配置实例 案例: http://www.cn ...

  4. 一个Java Dao测试用例

    import static org.junit.Assert.assertTrue; import java.util.Date; import java.util.HashMap; import j ...

  5. Reverse Words in a String

    void reverseWords(string &s) { string res = "", tmp = ""; int l = s.length() ...

  6. Cocos2d-x 3.4在AndroidStudio上编译配置

    转载请标明出处:http://www.cnblogs.com/studweijun/p/4320778.html 1.准备好以下文件 1) AndroidStudio:  https://dl.goo ...

  7. NetworkSocket结构图

    分层思想 NetworkSocket使用分层的思想,分基础层和上层: 1.基础层提供基础通讯,重要的对象有SessionBase.TcpServerBase和TcpClientBase: 2.上层实现 ...

  8. 无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支

    无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支.发布此分支将导致远程存储库中的分支发生非快进更新. 第一次用oschina的git设置完远程仓库后提交出现 ...

  9. poj-1314 Finding Rectangles

    题目地址: http://poj.org/problem?id=1314 题意: 给出一串的点,有些点可以构成正方形,请按照字符排序输出. 因为这道题的用处很大, 最近接触的cv 中的Rectangl ...

  10. vim 插件管理

    1 进入自己的vim mkdir ./bundle/vundle 2 在vimrc同级中执行 git clone https://github.com/gmarik/vundle.git ./bund ...