【洛谷 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) 注:洛谷测的时间浮动比较大 /* 插入一段数:将这些数先单独建一棵 ...
随机推荐
- 【OpenGL】无法启动此程序,因为计算机中丢失 glut32.dll。尝试重新安装该程序以解决此问题。
运行OpenGL程序的时候报错,如图: 解决方法:把glut32.dll复制到C:\Windows\SysWOW64目录下,而不是像网上教程那样复制到C:\Windows\System32目录下. 原 ...
- C# WebBrowser控件详解
作者:827969653 0.常用方法 Navigate(string urlString):浏览urlString表示的网址 Navigate(System.Uri url):浏览url表 ...
- Maven pom 文件解释
1 - 什么是构建? 我们都知道,写完代码之后需要进行编译和运行,以笔者自身为例,使用 Eclipse 写完代码,需要进行编译,再生成 war 包,以便部署到 Tomcat. 在编写 Java 代码的 ...
- 第14天:逻辑运算符、if、for语句
今天学习了逻辑运算符.if.for语句基础知识. 一.逻辑运算符 1.&&(与) 一假即假,同真为真2.||(或)一真即真,同假为假3.!(非)切记:参与逻辑运算的,都是布尔值.也就是 ...
- SQL查询数据总结
SQL查询数据 完整语法 Select [select选项] 字段列表[字段别名]/* from 数据源 [where条件子句] [group by子句] [having子句] [order by子句 ...
- usebean 使用语法
- bzoj1143-祭祀
题目 给出一个有向无环图,要在上面安放祭祀点.两个祭祀点必须不可达,求最多能安放多少个祭祀点. 分析 由于一条无法再延伸链上只能安放一个祭祀点,而我们要求的是最多能安放祭祀点的个数,所以要求的就是最长 ...
- CF546E Soldier and Traveling
题目描述 In the country there are n n n cities and m m m bidirectional roads between them. Each city has ...
- vue-router的钩子
vue-router的钩子分为三类: 1. 全局钩子2. 路由独享钩子3. 组件内钩子 1. 全局钩子 beforeEach(to,from,next) afterEach(route) 2. 路由独 ...
- 「LibreOJ NOIP Round #1」七曜圣贤
题目啰嗦:支持三个操作: 不可重复集合:1.加入一个数 2.删除一个数 3.恢复目前最早的一次删除的数 操作可能不合法,每次有效操作之后求集合的mex(最小没有出现过的数) 50组数据+1e6,必须O ...