[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 做法分析 好多不同的做法都可以 ...
随机推荐
- Ionic开发-如何在ion-content形成上下结构 上面固定下层可滚动
在一个系统设计中,一般有些需要固定位置,便利操作.现在我要做一个上下两层,需要固定上方,下方拉刷新数据. 页面: <ion-content scroll="false"> ...
- 前端之HTML语法及常用标签
html语法: 1.常规标记: <标记 属性=“属性值” 属性=“属性值”></标记>: 2.空标记: <标记 属性=“属性值” 属性=“属性值”/> 注意事项: ...
- maven编译报错 -source 1.5 中不支持 lambda(或diamond) 表达式,编码 UTF-8 的不可映射字符
在用maven编译项目是由于项目中用了jdk 1.8, 编译是报错 -source 1.5 中不支持 lambda 表达式. 错误原因: Maven Compiler 插件默认会加 -source ...
- ios https 安全证书配置
原定于2017年1月1日起所有提交到 App Store 的App必须强制开启 ATS,需要配置Https.但是现在不需要了,无固定期限的往后延期了,但是这个还是得弄明白下为好,说不定哪天突然就让弄了 ...
- git 配置免密上传,配置ssh key
1.windows 打开git bash 控制台,linux 直接打开命令控制台,输入 ssh-keygen 一直enter 下一步 2.生成的文件windows 存放在c://users 路径下,l ...
- mysql 查询数据库参数命令
1.select @@tx_isolation; 查询数据库设置的事务隔离级别 2.desc table_name; 显示表设计 3.show create table table_name; ...
- Android小玩意儿-- 从头开发一个正经的MusicPlayer(二)
1·在Service中实例化MusicPlayer,实现对整个播放过程的控制 上一次做到了找到音乐数据,并封装成对象装在ArrayList里,把数据的信息显示在UI上.下面一个阶段就要开始真正的音乐播 ...
- 关于bin和obj文件夹。debug 和release的区别(转)
关于bin和obj文件夹. 楼主hcaihao(影子男孩)2002-05-29 20:04:24 在 .NET技术 / C# 提问 VS.Net会生成bin和obj文件夹以及它们下面的Debug和Re ...
- (C#)Xamarin.ios 发布到 App Store
项目做到尾声了,IOS要发布,程序猿力Max来了. 不过就公司开发者账号就弄了一个月多,期间因为申请过D-U-N-S客服联系要公司资料时我们中途说取消了,后来再申请不知多少次了都没再回复... 给美国 ...
- windows安装tensorflow的一个教训
今天没什么课,然后就准备安装tensorflow. 看了一下教程,就去做了. 然后就犯了错误.网上的教程还是有一些差异的,而我又比较大意,没有很注意到CUDA,cudnn的版本要求,也过于高估自己cp ...