BZOJ 1507 Editor(块状链表)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1507
题意:一个文本编辑器,模拟以下操作:
思路:块状链表的主要操作:
(1)find(p,b):找到位置p在链表的位置b;
(2)split(b,p):将第b块分裂成两块,前一块大小为p;
(3)maintain(b):将b块之后的碎片合并;
利用以上三种操作可以完成插入串、删除一段串、得到一段串三种操作。另外三种操作比较简单。
(1)insert(p,n,str):在位置p之后插入长度为n的串str。find(p,b),split(b,p),之后将str插入b之后,最后maintain(b)一下;
(2)erase(p,n):在位置p之后删除长度为n的一段。find(p,b),split(b,p),之后从b之后删除若干块。这里可能最后一块也是需要split的。
(3)get(p,n):得到p之后长度为n的一段。find(p,b),split(b,p),之后从b之后取出长度为n的串,这里可能最后一个串也是需要split的。
const int N=1<<25;
const int BLOCKSIZE=20000;
const int BLOCKNUM=N/BLOCKSIZE*3;
queue<int> Q;
int newNode()
{
int temp=Q.front();
Q.pop();
return temp;
}
void delNode(int t)
{
Q.push(t);
}
struct node
{
char data[BLOCKSIZE];
int len,next;
};
node a[BLOCKNUM];
void find(int &p,int &b)
{
for(b=0;a[b].next!=-1&&p>a[b].len;b=a[b].next)
{
p-=a[b].len;
}
}
void fillNode(int b,int n,char data[],int nextB)
{
a[b].next=nextB;
a[b].len=n;
memcpy(a[b].data,data,n);
}
void split(int b,int p)
{
if(a[b].len==p) return;
int t=newNode();
fillNode(t,a[b].len-p,a[b].data+p,a[b].next);
a[b].next=t;
a[b].len=p;
}
void maintain(int b)
{
int t;
for(;b!=-1;b=a[b].next)
{
for(t=a[b].next;t!=-1&&a[b].len+a[t].len<=BLOCKSIZE;t=a[b].next)
{
memcpy(a[b].data+a[b].len,a[t].data,a[t].len);
a[b].len+=a[t].len;
a[b].next=a[t].next;
delNode(t);
}
}
}
void insert(int p,int n,char str[])
{
int i,b,t;
find(p,b); split(b,p);
for(i=0;i+BLOCKSIZE<=n;i+=BLOCKSIZE)
{
t=newNode();
fillNode(t,BLOCKSIZE,str+i,a[b].next);
a[b].next=t;
b=t;
}
if(i<n)
{
t=newNode();
fillNode(t,n-i,str+i,a[b].next);
a[b].next=t;
}
maintain(b);
}
void erase(int p,int n)
{
int i,b,t;
find(p,b); split(b,p);
for(i=a[b].next;i!=-1&&n>a[i].len;i=a[i].next)
{
n-=a[i].len;
}
split(i,n); i=a[i].next;
for(t=a[b].next;t!=i;t=a[b].next)
{
a[b].next=a[t].next;
delNode(t);
}
maintain(b);
}
void get(int p,int n,char str[])
{
int i,b,t;
find(p,b);i=min(n,a[b].len-p);
memcpy(str,a[b].data+p,i);
for(t=a[b].next;t!=-1&&i+a[t].len<=n;t=a[t].next)
{
memcpy(str+i,a[t].data,a[t].len);
i+=a[t].len;
}
if(i<n&&t!=-1) memcpy(str+i,a[t].data,n-i);
str[n]=0;
}
void init()
{
int i;
FOR1(i,BLOCKNUM-1) Q.push(i);
a[0].next=-1;
a[0].len=0;
}
char str[N];
void read(int n)
{
int i;
char c;
FOR0(i,n)
{
c=getchar();
str[i]=c;
if(c<32||c>126) i--;
}
}
int main()
{
init();
int cur=0;
char op[10];
int n;
rush()
{
RD(op);
if(op[0]=='M') RD(cur);
else if(op[0]=='I')
{
RD(n);
read(n);
insert(cur,n,str);
}
else if(op[0]=='D')
{
RD(n);
erase(cur,n);
}
else if(op[0]=='G')
{
RD(n);
get(cur,n,str);
puts(str);
}
else if(op[0]=='P') cur--;
else if(op[0]=='N') cur++;
}
}
BZOJ 1507 Editor(块状链表)的更多相关文章
- 【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor 块状链表模板题
2016-06-18 当时关于块状链表的想法是错误的,之前维护的是一个动态的$\sqrt{n}$,所以常数巨大,今天才知道原因TwT,请不要参照这个程序为模板!!! 模板题水啊水~~~ 第一次写块状链 ...
- 【BZOJ-1507】Editor 块状链表
1507: [NOI2003]Editor Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 3397 Solved: 1360[Submit][Stat ...
- 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();//插入是,也是头和尾暴力插入,中间那些加到一个累计里 ...
随机推荐
- Eclipse支持Jquery代码提示(JqeuryWTP)
问题描述: Eclipse支持Jquery代码提示 问题解决: 下载 JqueryWTP.jar文件 文件替换 在Eclipse/plugin 路径下, ...
- spring security 构造函数初始化bean思路
采用有参数的构造方法来解决注入你要的属性例如:public MyInvocationSecurityMetadataSource(RoleService roleService) { this.rol ...
- 修改MySQL数据库的密码
通过MySQL命令行,可以修改MySQL数据库的密码,下面就为您详细介绍该MySQL命令行,如果您感兴趣的话,不妨一看. 格式:mysql -u用户名 -p旧密码 password 新密码 1.给ro ...
- CodeForces 1B Spreadsheets (字符串处理,注意细节,大胆尝试)
题目 注意模后余数为0时,要把除以26后的新数据减1,为什么这样,要靠大胆尝试.我在对小比赛中坑了一下午啊,直到比赛结束也没写出这道题....要死了.. #include<stdio.h> ...
- ios滤镜
现在很多滤镜效果都写好了,搬运工的我直接拿来用(感谢
- DF学Mysql(三)——Mysql数据类型
Mysql数据类型分为:整数类型.浮点数类型.定点数类型日期与时间类型字符串类型二进制类型 整数类型 字节数 无符号数取值范围 有符号数取值范围TINYINT 1 0-255 -128-127SMAL ...
- db2日期和时间常用汇总
1.db2可以通过SYSIBM.SYSDUMMY1.SYSIBM.DUAL获取寄存器中的值,也可以通过VALUES关键字获取寄存器中的值. SELECT 'HELLO DB2' FROM SYSIBM ...
- 知问前端——创建header区
创建界面 我们首先要设计一个header,这个区域将要设计成永远置顶.也就是,往下拉出滚动条也永远在页面最上层可视区内.在header区,目前先设计LOGO.搜索框.按钮.注册和登录即可. 项目的大致 ...
- 很好的一款思维导图工具XMind使用教程
1.首先,下载并安装该软件Xmind.安装完毕后,在[开始菜单]寻找Xmind快捷方式,点击打开主程序. 2.打开时出现[新建]页面,可以选择创建空白主题的文档,也可以选择从模板创作.本例选择创建空白 ...
- redis专题--slow log详解
SLOWLOG subcommand [argument] 什么是 SLOWLOG Slow log 是 Redis 用来记录查询执行时间的日志系统. 查询执行时间指的是不包括像客户端响应(talki ...