复制炸格式了,就不贴题面了

[NOI2003] 文本编辑器

Solution

对于光标的移动,我们只要记录一下现在在哪里就可以了

Insert操作:手动维护中序遍历结果,即每次取中点像线段树一样一样递归建树,实际操作:把splay中的光标所在位置旋到根,光标后一位旋到根的下面,此时根的右节点的左子树是空的,直接插入我们所建的树的根即可

Delete:先找到我们要删除的是哪一段区间,把光标之前的点旋到根,终点之后的点旋到根的下面,直接扔掉根节点的右儿子的左子树即可

Get:也是找到区间递归中序输出就可以了

提示:为了防止越界,我在splay插入了两个换行符,保证题目输入不会出现就行,因此也要把光标初始值设为1

Code

#include<bits/stdc++.h>
#define il inline
#define rg register
#define lol long long
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b) using namespace std; const int N=1e6+10;
const int inf=2e9; void in(int &ans)
{
ans=0; int f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0', i=getchar();
ans*=f;
} int n,tot,m,now=1,root;
char s[N<<1]; struct Splay {
int f,size,ch[2];
Splay(){
size = ch[0] = ch[1] = 0;
}
char val;
}t[N<<1]; il bool get(int x) {
return t[t[x].f].ch[1]==x;
} il void up(int x) {
t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+1;
} void rotate(int x) {
int f=t[x].f,gf=t[f].f;
int k1=get(x),k2=get(f);
t[gf].ch[k2]=x,t[x].f=gf;
t[f].ch[k1]=t[x].ch[k1^1],t[t[x].ch[k1^1]].f=f;
t[x].ch[k1^1]=f,t[f].f=x;
up(f); up(x);
} void splay(int x,int goal) {
while(t[x].f!=goal) {
int f=t[x].f,gf=t[f].f;
if(gf!=goal) get(x)^get(f)?rotate(x):rotate(f);
rotate(x);
}
if(!goal) root=x;
} int kth(int k) {
int u=root;
while(1) {
int y=t[u].ch[0];
if(k>t[y].size+1)
u=t[u].ch[1],k-=t[y].size+1;
else if(k<=t[y].size) u=y;
else return u;
}
} il void Move() {
in(now); now++;
} il int add(char c,int f) {
t[++tot].val=c; t[tot].size=1;
t[tot].f=f; return tot;
} int build(int f,int l,int r,char *s) {
int mid=l+r>>1;
char ch=s[mid];
int u=add(ch,f);//按中序遍历建树
if(l<mid) t[u].ch[0]=build(u,l,mid-1,s);
if(mid<r) t[u].ch[1]=build(u,mid+1,r,s);
up(u); return u;
} void Insert() {
int x; in(x); strcpy(s,"");
for(rg int i=1;i<=x;i++) {
char ch=getchar();
while(ch==10 || ch==13 || ch<32 || ch>126) ch=getchar();
s[i]=ch;
}
int l=kth(now);
int r=kth(now+1);
splay(l,0); splay(r,l);
t[t[root].ch[1]].ch[0]=build(t[root].ch[1],1,x,s);
up(t[root].ch[1]); up(root);
} void Delete() {
int x; in(x);
int l=kth(now),r=kth(now+x+1);//r=kth((now+x-1)+1+1)第一个+1指光标指到起点,因为实际上光标指的是起点-1所以要加回来,第二个+1指区间终点的后一个端点
splay(l,0); splay(r,l);
int u=t[root].ch[1];
t[u].ch[0]=0;
up(u); up(root);
} void out(int u) {
if(t[u].ch[0]) out(t[u].ch[0]);
if(t[u].val!='\n') putchar(t[u].val);
if(t[u].ch[1]) out(t[u].ch[1]);
} void Get() {
int x; in(x);
int l=kth(now),r=kth(now+x+1);
splay(l,0); splay(r,l);
out(t[t[root].ch[1]].ch[0]);
putchar('\n');
} int main()
{
//freopen("data.in", "r", stdin);
root=add('\n',0),t[root].ch[1]=add('\n',root);up(root);
in(n); char s[10];
while(n--) {
scanf("%s",s);
if(s[0]=='M') Move();
if(s[0]=='I') Insert();
if(s[0]=='D') Delete();
if(s[0]=='G') Get();
if(s[0]=='P') now--;
if(s[0]=='N') now++;
}
return 0;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

[NOI2003] 文本编辑器 (splay)的更多相关文章

  1. luogu P4008 [NOI2003]文本编辑器 splay 块状链表

    LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...

  2. 洛谷 P4008 [NOI2003]文本编辑器 解题报告

    P4008 [NOI2003]文本编辑器 题目描述 很久很久以前,\(DOS3.x\)的程序员们开始对 \(EDLIN\) 感到厌倦.于是,人们开始纷纷改用自己写的文本编辑器⋯⋯ 多年之后,出于偶然的 ...

  3. [NOI2003]文本编辑器 [Fhq Treap]

    [NOI2003]文本编辑器 没啥好说的 就是个板子 #include <bits/stdc++.h> // #define int long long #define rep(a , b ...

  4. [AHOI2006]文本编辑器 Splay tree区间操作

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1269 Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个 ...

  5. BZOJ 1269 文本编辑器 Splay

    题目大意:维护一个文本编辑器,支持下列操作: 1.将光标移动到某一位置 2.在光标后插入一段字符串 3.删除光标后的一段字符 4.翻转光标后的一段字符 5.输出光标后的一个字符 6.光标-- 7.光标 ...

  6. cogs 330. [NOI2003] 文本编辑器

    ★★★   输入文件:editor2003.in   输出文件:editor2003.out   简单对比 时间限制:2 s   内存限制:128 MB [问题描述] 很久很久以前,DOS3.x的程序 ...

  7. 【洛谷 P4008】 [NOI2003]文本编辑器 (Splay)

    题目链接 \(Splay\)先练到这吧(好像还有道毒瘤的维护数列诶,算了吧) 记录下光标的编号,维护就是\(Splay\)基操了. 另外数据有坑,数据是\(Windows\)下生成了,回车是'\n\r ...

  8. NOI2003 文本编辑器editor

    1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 1908  Solved: 738[Submit][Statu ...

  9. HYSBZ 1269文本编辑器 splay

    比较基本的操作. #include<map> #include<queue> #include<stack> #include<cmath> #incl ...

随机推荐

  1. python3 练习题100例 (二十一)打印一定范围内的水仙花数

    题目内容: 水仙花数是指一个n位数 (n≥3),它的每个位上的数字的n次幂之和等于它本身. 例如:153是一个“水仙花数”,因为 153 是个 3位数,而1**3+5**3+3**3==153. 输入 ...

  2. kuangbin 最小生成树

    A & M - Jungle Roads HDU - 1301 题意:字母之间的路,求最小生成树 题解:处理好建边以后就是一个Prime #include<cstdio> #inc ...

  3. 嵌入式框架Zorb Framework搭建六:定时器的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  4. Failed to read candidate component class错误分析

    org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component c ...

  5. Go语言使用百度翻译api

    Go语言使用百度翻译api 之前做过一个使用百度翻译api的工具,这个工具用于用户的自动翻译功能,是使用C#调用百度翻译api接口,既然在学习Go语言,那必然也是要使用Go来玩耍一番.这里我是这么安排 ...

  6. Python正则表达式中的re.S,re.M,re.I的作用

    正则表达式可以包含一些可选标志修饰符来控制匹配的模式.修饰符被指定为一个可选的标志.多个标志可以通过按位 OR(|) 它们来指定.如 re.I | re.M 被设置成 I 和 M 标志: 修饰符 描述 ...

  7. java容器操作一

    List l = new ArrayList(); l.add(1); l.add("ne"); // 获取 System.out.println(l.get(0)); // 判断 ...

  8. 不同浏览器css引入外部字体的方式

    /** * 字体后缀和浏览器有关,如下所示 * .TTF或.OTF,适用于Firefox 3.5.Safari.Opera * .EOT,适用于Internet Explorer 4.0+ * .SV ...

  9. Qt Qwdget 汽车仪表知识点拆解5 标题栏图标闪烁

    先贴上效果图,注意,没有写逻辑,都是乱动的 看下最上面的部分,有一些仪表图标在闪烁,如果一个一个写,也是可以实现的,不过感觉要累死的节奏 这里我写了一个我自己的Label,完了把把这些QLabel提升 ...

  10. 怎样安装Python3

    在浏览器地址栏输入https://www.python.org/ 打开Python官网 好了,安装完成了! 可以把安装路径C:\Users\Administrator\AppData\Local\Pr ...