【BZOJ-1507】Editor 块状链表
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
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 块状链表的更多相关文章
- 【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor   块状链表模板题
		
2016-06-18 当时关于块状链表的想法是错误的,之前维护的是一个动态的$\sqrt{n}$,所以常数巨大,今天才知道原因TwT,请不要参照这个程序为模板!!! 模板题水啊水~~~ 第一次写块状链 ...
 - BZOJ 1507 Editor(块状链表)
		
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1507 题意:一个文本编辑器,模拟以下操作: 思路:块状链表的主要操作: (1)find( ...
 - BZOJ 3217: ALOEXT (块状链表套trie)
		
第一次写块状链表,发现还挺好写的,但是一点地方写错加上强制在线就会各种姿势WA/TLE/RE爆- 想法就是分块后,在每一个块上维护最大值和次大值,还在每一个块上维护一棵trie树来求异或最大值.散块直 ...
 - BZOJ 1507 Editor
		
Description Input 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它 ...
 - BZOJ 4864: [BeiJing 2017 Wc]神秘物质 (块状链表/平衡树 )
		
这就是一道数据结构裸题啊,最大极差就是区间最大值减最小值,最小极差就是相邻两个数差的最小值.然后平衡树splay/treap或者块状链表维护就行了. 第一次自己写块状链表,蛮好写,就是长..然后就BZ ...
 - bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)
		
[题意] 回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]. [思路] 考虑使用块状链表实现莫队算法中的插入与删除. 因为权值处于1..n之间,所以我们可以建一个基 ...
 - 洛谷.4008.[NOI2003]editor文本编辑器(块状链表)
		
题目链接 st(n)表示sqrt(n) 为使块状链表不会退化,通常将每块的大小S维持在[st(n)/2,2st(n)]中,这样块数C也一定[st(n)/2,2st(n)]中 在此使用另一种方法(方便) ...
 - [NOI2003]Editor(块状链表)
		
传送门 看了看块状链表,就是数组和链表的合体. 看上去好高大尚,思想也很简单. 但是发现代码量也不是很小,而且代码理解起来也是费尽得很,倒不如splay用起来顺手. 在加上适用范围貌似不是特别广,所以 ...
 - 块状链表 bzoj 3343教主的魔法
		
//块状链表//分块排序,然后每次查找时在暴力查找头和尾两个块.//中间那些块,因为有序所以只需2分查找即可.我用的是lower_pound();//插入是,也是头和尾暴力插入,中间那些加到一个累计里 ...
 
随机推荐
- ES6  WeakSet数据结构 与Set十分相似
			
它与Set十分相似,对象的值也不能是重复的,与Set不同点: .WeakSet成员只能够是对象. .作为WeakSet成员的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说, ...
 - Java 读取xlsx
			
读取特别大的xlsx文件时, 需要使用StreamingReader, 可以控制JVM内存峰值在200M以内 InputStream is = new FileInputStream(new File ...
 - spring mvc总结1
			
1,spring下载 spring更改了官方网站后,找了很长时间没有找到相关的jar包下载路径,然后在网上终于找到相关的路径了 有个树形结构可供选择:http://repo.spring.io/rel ...
 - mysql游标循环的使用
			
CREATE PROCEDURE `test`.`new_procedure` () BEGIN DECLARE done INT DEFAULT FALSE; -- 需要定义接收游标数据的变量 ); ...
 - .net core API 统一拦截错误
			
public override void OnActionExecuted(ActionExecutedContext context) { if (context.Exception != null ...
 - 学习jQuery的on事件
			
开发asp.net mvc程序,多少是离不开jQuery客户程序.今天Insus.NET学习jQuery的一个on事件驱动. 先在网页视图放一个图片铵钮,用户可以使用mouse对这图片时行over,o ...
 - openwrt编译出错处理记录
			
1.代码从windows复制过来编译报错处理,参考:http://www.360doc.com/content/13/1016/21/3884271_321966616.shtml 2.编译lua-s ...
 - nfs 三个参数权限
			
遇到nfs客户端不可写的情况. 有延迟啊啊啊.. 等1min左右就可以写了. 挂载参数: cat /var/lib/nfs/etab -->server cat /proc/mounts ...
 - XMLHTTPRequest/Ajax请求 和普通请求的区别
			
Ajax请求头会多一个x-requested-with参数,值为XMLHttpRequest 详情:http://blog.csdn.net/zhangdaiscott/article/details ...
 - mysql 控制台上传数据库
			
运行 0.cmd1.cd/d d:\DedeAMPZ\Program\MySQL\bin2.mysql -uroot -p1234563.use 数据库名4.source XX.sql 文件所在路 ...