[NOI2003]Editor(块状链表)
看了看块状链表,就是数组和链表的合体。
看上去好高大尚,思想也很简单。
但是发现代码量也不是很小,而且代码理解起来也是费尽得很,倒不如splay用起来顺手。
在加上适用范围貌似不是特别广,所以只把模板贴在这,只当了解思想,暂时先不使用。(也不会用啊)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std; const int N=<<;
const int blocksize=;
const int blocknum=N/blocksize*; int T,_;
int cur;
char str[],opt[];
queue <int> q;
struct node
{
char data[blocksize+];
int len,nxt;
}a[blocknum+]; void init()
{
for (int i=;i<=blocknum;++i) q.push(i);
a[].len=; a[].nxt=-;
}
void read(int len)
{
int i=-;
while (i<len-)
{
i++;
char c=getchar();
str[i]=c;
if (c<||c>) i--;
}
}
//新开一个块的节点
int newnode()
{
int temp=q.front(); q.pop();
return temp;
}
//回收块的节点
void delnode(int t)
{
q.push(t);
}
//找到pos所在的块,并使pos表示在当前块中的位置
void find(int &pos,int &now)
{
for (now=;a[now].nxt!=-&&pos>a[now].len;now=a[now].nxt)
pos-=a[now].len;
}
//将新快赋值
void fillnode(int pos,int n,char data[],int nxt)
{
a[pos].nxt=nxt; a[pos].len=n;
memcpy(a[pos].data,data,n);
}
//将块pos在p位置前后分开,变成两个块
void split(int pos,int p)
{
if (a[pos].len==p) return;
int t=newnode();
fillnode(t,a[pos].len-p,a[pos].data+p,a[pos].nxt);
a[pos].nxt=t; a[pos].len=p;
}
//把碎块合并
void maintain(int pos)
{
int t;
for (;pos!=-;pos=a[pos].nxt)
for (t=a[pos].nxt;t!=-&&a[pos].len+a[t].len<blocksize;t=a[t].nxt)
{
memcpy(a[pos].data+a[pos].len,a[t].data,a[t].len);
a[pos].len+=a[t].len; a[pos].nxt=a[t].nxt; delnode(t);
}
}
//在光标pos处插入长度为n的str
void insert(int pos,int n)
{
int now,i,t;
//now表示光标所在的块,pos表示光标在这个块中的位置
find(pos,now);
split(now,pos);
for (i=;i+blocksize<=n;i+=blocksize)
{
t=newnode();
fillnode(t,blocksize,str+i,a[now].nxt);
a[now].nxt=t;
now=t;
}
if (i<n)
{
t=newnode();
fillnode(t,n-i,str+i,a[now].nxt);
a[now].nxt=t;
}
maintain(now);
}
//从光标pos开始删除长度为n的字符串
void del(int pos,int n)
{
int i,now,t;
//now表示光标所在的块,pos表示光标在这个块中的位置
find(pos,now);
split(now,pos);
//找到删除的末尾的点所处的块
for (i=a[now].nxt;i!=-&&n>a[i].len;i=a[i].nxt)
n-=a[i].len;
split(i,n); i=a[i].nxt;
for (t=a[now].nxt;t!=i;t=a[now].nxt)
a[now].nxt=a[t].nxt,delnode(t);
maintain(now);
}
//从pos这个位置开始输出长度为n的字符串
void get(int pos,int n)
{
int i,now,t;
find(pos,now);
i=min(n,a[now].len-pos);
memcpy(str,a[now].data+pos,i);
for (t=a[now].nxt;t!=-&&i+a[t].len<=n;t=a[t].nxt)
{
memcpy(str+i,a[t].data,a[t].len);
i+=a[t].len;
}
if (i<n&&t!=-) memcpy(str+i,a[t].data,n-i);
str[n]=;
}
int main()
{
init();
scanf("%d",&T);
while (T--)
{
scanf("%s",opt);
if (opt[]=='M') scanf("%d",&cur);//改变光标的位置
if (opt[]=='I')//插入一段区间
{
scanf("%d",&_);
read(_);
insert(cur,_);
}
if (opt[]=='P') cur--;//光标左移
if (opt[]=='N') cur++;//光标右移
if (opt[]=='D')//删除一段区间
{
scanf("%d",&_);
del(cur,_);
}
if (opt[]=='G')//输出一段区间
{
scanf("%d",&_);
get(cur,_);
puts(str);
}
}
}
[NOI2003]Editor(块状链表)的更多相关文章
- 【BZOJ-1507】Editor 块状链表
1507: [NOI2003]Editor Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 3397 Solved: 1360[Submit][Stat ...
- 【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor 块状链表模板题
2016-06-18 当时关于块状链表的想法是错误的,之前维护的是一个动态的$\sqrt{n}$,所以常数巨大,今天才知道原因TwT,请不要参照这个程序为模板!!! 模板题水啊水~~~ 第一次写块状链 ...
- 洛谷.4008.[NOI2003]editor文本编辑器(块状链表)
题目链接 st(n)表示sqrt(n) 为使块状链表不会退化,通常将每块的大小S维持在[st(n)/2,2st(n)]中,这样块数C也一定[st(n)/2,2st(n)]中 在此使用另一种方法(方便) ...
- 1507: [NOI2003]Editor(块状链表)
1507: [NOI2003]Editor Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4157 Solved: 1677[Submit][Stat ...
- BZOJ 1507 Editor(块状链表)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1507 题意:一个文本编辑器,模拟以下操作: 思路:块状链表的主要操作: (1)find( ...
- luogu P4008 [NOI2003]文本编辑器 splay 块状链表
LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...
- 1507: [NOI2003]Editor
1507: [NOI2003]Editor Time Limit: 5 Sec Memory Limit: 162 MB Submit: 3535 Solved: 1435 [Submit][St ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- POJ 2887 Big String(块状链表)
题目大意 给一个字符串,长度不超过 106,有两种操作: 1. 在第 i 个字符的前面添加一个字符 ch 2. 查询第 k 个位置是什么字符 操作的总数不超过 2000 做法分析 好多不同的做法都可以 ...
随机推荐
- PV,UV,IP概念
PV是网站分析的一个术语,用以衡量网站用户访问的网页的数量.对于广告主,PV值可预期它可以带来多少广告收入.一般来说,PV与来访者的数量成正比,但是PV并不直接决定页面的真实来访者数量,如同一个来访者 ...
- Hadoop工作流概念学习系列总述(一)
不多说,这里,直接上干货!从这篇博客起,逐步分享如下: 1.工作流 2.Hadoop工作流(内置) 3.第三方框架--Azkaban(推荐外安装)
- dangerouslySetHTML 和 style 属性
这一节我们来补充两个之前没有提到的属性,但是在 React.js 组件开发中也非常常用,但是它们也很简单. dangerouslySetHTML 出于安全考虑的原因(XSS 攻击),在 React.j ...
- nodejs的mysql模块学习笔记(结合业务)
1. 包官网地址 https://www.npmjs.com/package/mysql#install https://www.oschina.net/translate/node-mysql-tu ...
- 【转】java节省内存的几条建议
下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单 ...
- REST风格笔记
这一篇主要是看了FB的覃超大大的文章,做了一些笔记和自己的思考. 定义: 用URL来定义资源,用HTTP(GET/POST/DELETE/DETC)来描述操作. 1. REST描述的是网络 ...
- P3368 【模板】树状数组 2 单点查询与区间修改
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...
- Python学习日记之Python函数及方法使用总结
1. DocStrings 文档字符串 可以直接输出位于函数内定义的说明 # -*- coding:utf-8 -*- def printMax(x, y): '''示例: 说明文档''' ...
- 诊断Java代码中常见的数据库性能热点问题应该这么做!
“你的Java应用程序的性能是怎样诊断和优化的?不妨看看这两位西医的方子.如果你有更好疗效的药方,也欢迎在评论区告诉我们. 当我在帮助一些开发者或架构师分析及优化Java应用程序的性能时,关键往往不在 ...
- Mac 创建软链接
ln -s /Volumes/dzqExt/source/wukongqipai/wukongqipai/ccclient/Classes/ ./frameworks/runtime-src/ ...