【洛谷 P4008】 [NOI2003]文本编辑器 (Splay)
题目链接
\(Splay\)先练到这吧(好像还有道毒瘤的维护数列诶,算了吧)
记录下光标的编号,维护就是\(Splay\)基操了。
另外数据有坑,数据是\(Windows\)下生成了,回车是'\n\r',我就被坑了。
#include <cstdio>
#include <algorithm>
using namespace std;
inline int read(){
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0',ch = getchar();
return s * w;
}
const int MAXINSERTLEN = 10000010;
struct SplayTree{
char val;
int ch[2], fa, size;
}t[MAXINSERTLEN];
char str[MAXINSERTLEN];
int num, root, n, len;
void pushup(int u){
t[u].size = t[t[u].ch[0]].size + t[t[u].ch[1]].size + 1;
}
void rotate(int x){
int y = t[x].fa; int z = t[y].fa; int k = t[y].ch[1] == x;
t[z].ch[t[z].ch[1] == y] = x; t[x].fa = z;
t[y].ch[k] = t[x].ch[k ^ 1]; t[t[x].ch[k ^ 1]].fa = y;
t[x].ch[k ^ 1] = y; t[y].fa = x;
pushup(y); pushup(x);
}
void Splay(int x, int goal){
while(t[x].fa != goal){
int y = t[x].fa; int z = t[y].fa;
if(z != goal)
(t[z].ch[0] == y) ^ (t[y].ch[0] == x) ? rotate(x) : rotate(y);
rotate(x);
}
if(goal == 0) root = x;
}
int build(int l, int r){
int id = ++num;
int mid = (l + r) >> 1;
t[id].val = str[mid];
if(mid > l){
t[id].ch[0] = build(l, mid - 1);
t[t[id].ch[0]].fa = id;
}
if(mid < r){
t[id].ch[1] = build(mid + 1, r);
t[t[id].ch[1]].fa = id;
}
pushup(id);
return id;
}
inline int findKth(int k){
int u = root;
while(1){
if(t[t[u].ch[0]].size >= k) u = t[u].ch[0];
else if(t[t[u].ch[0]].size == k - 1) return u;
else k -= t[t[u].ch[0]].size + 1, u = t[u].ch[1];
}
}
inline int next(int x, int mode){
Splay(x, 0);
int u = t[x].ch[mode]; mode ^= 1;
while(t[u].ch[mode]) u = t[u].ch[mode];
return u;
}
char opt;
int cur;
void print(int x){
if(t[x].ch[0]) print(t[x].ch[0]);
if(t[x].val != 1) printf("%c", t[x].val);
if(t[x].ch[1]) print(t[x].ch[1]);
}
int main(){
n = read();
root = cur = ++num; t[num].val = 1;
t[++num].fa = cur; t[num].val = 1;
t[cur].ch[1] = num; t[num].size = 1; t[cur].size = 2;
for(int i = 1; i <= n; ++i){
opt = getchar();
while(opt < 'A' || opt > 'Z') opt = getchar();
if(opt == 'I'){
len = read();
for(int i = 1; i <= len; ++i){
str[i] = getchar();
while(str[i] < 32 || str[i] > 126) str[i] = getchar();
}
Splay(cur, 0);
Splay(next(cur, 1), cur);
t[t[root].ch[1]].ch[0] = (len = build(1, len));
t[len].fa = t[root].ch[1];
Splay(t[t[root].ch[1]].ch[0], 0);
}
else if(opt == 'G'){
len = read();
Splay(cur, 0);
Splay(findKth(t[t[root].ch[0]].size + 2 + len), root);
print(t[t[root].ch[1]].ch[0]);
putchar('\n');
}
else if(opt == 'M')
cur = findKth(read() + 1);
else if(opt == 'P')
cur = next(cur, 0);
else if(opt == 'N')
cur = next(cur, 1);
else if(opt == 'D'){
len = read();
Splay(cur, 0);
Splay(findKth(t[t[root].ch[0]].size + 2 + len), root);
t[t[root].ch[1]].ch[0] = 0;
}
}
return 0;
}
【洛谷 P4008】 [NOI2003]文本编辑器 (Splay)的更多相关文章
- 洛谷 P4008 [NOI2003]文本编辑器 解题报告
P4008 [NOI2003]文本编辑器 题目描述 很久很久以前,\(DOS3.x\)的程序员们开始对 \(EDLIN\) 感到厌倦.于是,人们开始纷纷改用自己写的文本编辑器⋯⋯ 多年之后,出于偶然的 ...
- 洛谷 P4008 [NOI2003]文本编辑器
先推广一下 求赞 我们考虑这样的一个问题 给你一个序列,要求你支持插入,删除,查询单点值 如果用数组,查询O(1),插入删除最坏O(n) 如果用链表,插入删除O(1),查询最坏O(n) 如果用平衡树- ...
- luogu P4008 [NOI2003]文本编辑器 splay 块状链表
LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...
- [NOI2003] 文本编辑器 (splay)
复制炸格式了,就不贴题面了 [NOI2003] 文本编辑器 Solution 对于光标的移动,我们只要记录一下现在在哪里就可以了 Insert操作:手动维护中序遍历结果,即每次取中点像线段树一样一样递 ...
- P4008 [NOI2003]文本编辑器
思路 FHQ Treap的板子 用FHQ Treap维护中序遍历序列即可 然后数组开够! 代码 #include <cstdio> #include <cstring> #in ...
- [洛谷日报第62期]Splay简易教程 (转载)
本文发布于洛谷日报,特约作者:tiger0132 原地址 分割线下为copy的内容 [洛谷日报第62期]Splay简易教程 洛谷科技 18-10-0223:31 简介 二叉排序树(Binary Sor ...
- [NOI2003]文本编辑器 [Fhq Treap]
[NOI2003]文本编辑器 没啥好说的 就是个板子 #include <bits/stdc++.h> // #define int long long #define rep(a , b ...
- [AHOI2006]文本编辑器 Splay tree区间操作
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1269 Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个 ...
- BZOJ 1269 文本编辑器 Splay
题目大意:维护一个文本编辑器,支持下列操作: 1.将光标移动到某一位置 2.在光标后插入一段字符串 3.删除光标后的一段字符 4.翻转光标后的一段字符 5.输出光标后的一个字符 6.光标-- 7.光标 ...
- 洛谷.2042.[NOI2005]维护数列(Splay)
题目链接 2017.12.24 第一次写: 时间: 2316ms (1268ms) 空间: 19.42MB (19.5MB)(O2) 注:洛谷测的时间浮动比较大 /* 插入一段数:将这些数先单独建一棵 ...
随机推荐
- android入门 — ListView
ListView主要是用来解决大量数据展示的问题,它的用途很广泛,几乎所有的app都会用到,比如说知乎.今日头条.微博.通讯录等. ListView允许用户通过上下滑动的方式将屏幕外的数据滚动到屏幕中 ...
- LintCode-159.寻找旋转排序数组中的最小值
寻找旋转排序数组中的最小值 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 你可以假设数组中不存在重复的 ...
- 提升MyEclipse运行速度
修改MyEclipse.ini文件中的,将-vmargs后面的参数修改为 -Xms256m -Xmx768m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:Max ...
- title & abbr & tooltips
title & abbr & tooltips https://dmitrybaranovskiy.github.io/raphael/ <abbr title="Sc ...
- js alert()后进行跳转的方法
如果alert()之后再进行跳转本页,按以下方法你将等不到alert(),浏览器就本身刷新本页面了 <script type="text/javascript"> al ...
- UIKit中的几个核心对象的介绍:UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍
UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍 一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道 ...
- P1667 数列
题目描述 给定一个长度是n的数列A,我们称一个数列是完美的,当且仅当对于其任意连续子序列的和都是正的.现在你有一个操作可以改变数列,选择一个区间[X,Y]满足Ax +Ax+1 +…+ AY<0, ...
- 后缀自动机SAM学习笔记
前言(2019.1.6) 已经是二周目了呢... 之前还是有一些东西没有理解到位 重新写一下吧 后缀自动机的一些基本概念 参考资料和例子 from hihocoder DZYO神仙翻译的神仙论文 简而 ...
- BZOJ4870:[SHOI2017]组合数问题——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=4870 https://www.luogu.org/problemnew/show/P3746 看网上 ...
- URAL1297:Palindrome——题解
http://acm.timus.ru/problem.aspx?space=1&num=1297 https://vjudge.net/problem/URAL-1297 给定一个字符串,求 ...