[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 做法分析 好多不同的做法都可以 ...
随机推荐
- qconshanghai2016
http://2016.qconshanghai.com/schedule 大会日程 2016年10月20日 星期四 07:45 开始签到 09:00 开场致辞 专题 前端技术实践 主题演讲 业务上云 ...
- 组件的 state 和 setState
state 我们前面提到过,一个组件的显示形态是可以由它数据状态和配置参数决定的.一个组件可以拥有自己的状态,就像一个点赞按钮,可以有“已点赞”和“未点赞”状态,并且可以在这两种状态之间进行切换.Re ...
- Bean with name 'xxxService' has been injected into other beans [xxxServiceA,xxxServiceB] in its raw version as part of a circular reference, but has eventually been wrapped
启动项目,通过@Autowired注入对象,出现循环依赖,导致项目启动失败,具体报错信息如下: Exception encountered during context initialization ...
- Javaweb学习笔记10—文件上传与下载
今天来讲javaweb的第10阶段学习.文件的上传与下载,今天主要说的是这个功能的实现,不用说了,听名字就是外行人也知道肯定很重要啦. 老规矩,首先先用一张思维导图来展现今天的博客内容. ...
- IE8 window.open 不支持此接口 的问题解决
在使用vs2010调试代码时,突然出现 window.open 不支持此接口的提示,开始认为是不是vs的问题,后来上网查询说是系统问题.我不想重装系统,之后发现是IE的问题,使用其他浏览器浏览系统不会 ...
- 利用Jenkins打包ISO和QCOW2镜像文件
现在的云虚拟化环境越来越多,经常会碰到需要修改并重新打包新的ISO或QCOW2镜像文件.通过手工的方式会比较麻烦,所以在镜像发布的生产环境中可以利用Jenkins来进行定期打包发布,以下介绍Jenki ...
- 如何在Ubuntu里安装Helm
Helm是什么?在战网上玩过暗黑破坏神2代的程序员们应该还记得,Helm是国度的意思. 而在计算机领域,Helm是什么? Helm是Kubernetes的一个包管理工具,有点像nodejs的npm,U ...
- javaee 第五周作业
一.Ajax技术 AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. ...
- XtraBackUp 热备份工具
是一款强大的在线热备份工具 备份的过程中,不锁表 使用percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm yum源安装: 1.安装Percona的库: ...
- c语言 错误记录
1.预处理错误 #include <> //系统内部的 #include "" // 自定义的 遇到 not find------解决方案:gcc -I 跟查找 ...