题目大意:维护一个文本编辑器,支持下列操作:

1.将光标移动到某一位置

2.在光标后插入一段字符串

3.删除光标后的一段字符

4.翻转光标后的一段字符

5.输出光标后的一个字符

6.光标--

7.光标++

Splay中比較水的一道题,标记仅仅有区间翻转,也不用维护区间总值,只有须要注意的就是插入的时候fa要记得赋值,不然就会像本蒟蒻一样调半天,,,

这题要注意的是Insert操作的读入 首先读入第一个不是'\n'或者'\r'的字符,然后假设长度不为1就继续gets() 记住是get()不是scanf

然后就没啥了。。。 20%达成 啊啊爽翻天

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct abcd{
abcd *fa,*ls,*rs;
char c;
int siz;
bool rev_mark;
abcd (char C);
void Reverse();
void Push_Up();
void Push_Down();
}*null=new abcd(0),*root=null;
abcd :: abcd(char C)
{
fa=ls=rs=null;
c=C;
siz=C?1:0;
rev_mark=0;
}
void abcd :: Reverse()
{
rev_mark^=1;
swap(ls,rs);
}
void abcd :: Push_Up()
{
siz=ls->siz+rs->siz+1;
}
void abcd :: Push_Down()
{
if(rev_mark)
{
ls->Reverse();
rs->Reverse();
rev_mark=0;
}
}
void Zig(abcd *x)
{
abcd *y=x->fa;
y->ls=x->rs;
x->rs->fa=y;
x->rs=y;
x->fa=y->fa;
if(y==y->fa->ls)
y->fa->ls=x;
else if(y==y->fa->rs)
y->fa->rs=x;
y->fa=x;
y->Push_Up();
if(y==root)
root=x;
}
void Zag(abcd *x)
{
abcd *y=x->fa;
y->rs=x->ls;
x->ls->fa=y;
x->ls=y;
x->fa=y->fa;
if(y==y->fa->ls)
y->fa->ls=x;
else if(y==y->fa->rs)
y->fa->rs=x;
y->fa=x;
y->Push_Up();
if(y==root)
root=x;
}
void Splay(abcd *x,abcd *Tar)
{
while(1)
{
abcd *y=x->fa,*z=y->fa;
if(y==Tar)
break ;
if(z==Tar)
{
if(x==y->ls)
Zig(x);
else
Zag(x);
break;
}
if(x==y->ls)
{
if(y==z->ls)
Zig(y);
Zig(x);
}
else
{
if(y==z->rs)
Zag(y);
Zag(x);
}
}
x->Push_Up();
}
void Find(abcd *x,int y,abcd *z)
{
while(1)
{
x->Push_Down();
if(y<=x->ls->siz)
x=x->ls;
else
{
y-=x->ls->siz;
if(y==1)
break;
y--;
x=x->rs;
}
}
Splay(x,z);
}
char s[1<<21];
void Build_Tree(abcd *&x,int l,int r)
{
if(l>r)
return ;
int mid=l+r>>1;
x=new abcd(s[mid]);
Build_Tree(x->ls,l,mid-1);
Build_Tree(x->rs,mid+1,r);
if(x->ls!=null)
x->ls->fa=x;
if(x->rs!=null)
x->rs->fa=x;
x->Push_Up();
}
int cursor,m;
int main()
{
int i,x;
char p[100];
cin>>m;
{
root=new abcd('\n');
root->rs=new abcd('\n');
root->rs->fa=root;
root->Push_Up();
}
for(i=1;i<=m;i++)
{
scanf("%s",p);
if(p[0]=='M')
scanf("%d",&cursor);
else if(p[0]=='I')
{
scanf("%d",&x);
do s[0]=getchar(); while(s[0]=='\n'||s[0]=='\r');
if(x^1) gets(s+1);
Find(root,cursor+1,null);
Find(root,cursor+2,root);
Build_Tree(root->rs->ls,0,x-1);
root->rs->ls->fa=root->rs;
root->rs->Push_Up();
root->Push_Up();
}
else if(p[0]=='D')
{
scanf("%d",&x);
Find(root,cursor+1,null);
Find(root,cursor+x+2,root);
root->rs->ls=null;
root->rs->Push_Up();
root->Push_Up();
}
else if(p[0]=='R')
{
scanf("%d",&x);
Find(root,cursor+1,null);
Find(root,cursor+x+2,root);
root->rs->ls->Reverse();
}
else if(p[0]=='G')
{
Find(root,cursor+2,null);
printf("%c\n",root->c);
}
else if(p[0]=='P')
cursor--;
else
cursor++;
}
}

BZOJ 1269 文本编辑器 Splay的更多相关文章

  1. BZOJ 1269 文本编辑器editor(伸展树)

    题意 https://www.lydsy.com/JudgeOnline/problem.php?id=1269 思路 伸展树(\(\text{splay}\))功能比较齐全的模板,能较好的体现 \( ...

  2. HYSBZ 1269文本编辑器 splay

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

  3. [AHOI 2006][BZOJ 1269]文本编辑器editor

    好吧,我承认这是我用来刷随笔数的喵~ 这是一道 splay 裸题,但还是有想本傻 X 一样根本不会写 splay 的,于是乎又用 treap 水过了 splay 的常数我还是知道的,所以真是不知道那些 ...

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

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

  5. [NOI2003] 文本编辑器 (splay)

    复制炸格式了,就不贴题面了 [NOI2003] 文本编辑器 Solution 对于光标的移动,我们只要记录一下现在在哪里就可以了 Insert操作:手动维护中序遍历结果,即每次取中点像线段树一样一样递 ...

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

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

  7. BZOJ 1269: [AHOI2006]文本编辑器editor( splay )

    splay..( BZOJ 1507 题目基本相同..双倍经验 ) ------------------------------------------------------------------ ...

  8. 【BZOJ】1269: [AHOI2006]文本编辑器editor(Splay)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1269 这题RE2次啊,好不爽啊,我一直以为是splay的问题,其实是数组开小了......(我老犯这 ...

  9. BZOJ 1269: [AHOI2006]文本编辑器editor (splay tree)

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1213  Solved: 454[Submit ...

随机推荐

  1. MFC程序的消息处理顺序

    MFC应用程序中处理消息的顺序 1.AfxWndProc()      该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc()  该 ...

  2. C++ delete 和 delete []

    C++ delete 和 delete [] 简单结论: new delete new [] delete []   文章 : 对 delete [] 的声明 void operator delete ...

  3. Sql Server中COUNT(字段名)跟COUNT(*)的特殊不同点

    今天有个需求,有2张表: 1.一个“搜索记录”表search,一个“搜索后下载记录”表down 2.映射关系:每一个下载记录对应一条搜索记录,                           第个 ...

  4. MySQL 存储过程例子,不能在if else里面用begin end否则会报错Error Code : 1064!

    Error Code : 1064 You have an error in your SQL syntax; check the manual that corresponds to your My ...

  5. Swift - 使用导航条和导航条控制器来进行页面切换

    通过使用导航条(UINavigationBar)与导航条控制器(UINavigationController)可以方便的在主页面和多层子页面之间切换.下面通过一个简单“组件效果演示”的小例子来说明如何 ...

  6. javascript(五)验证

    <input id="domo"  type="text"> <script> function my_function(){ var ...

  7. haproxy 看到的是https,后台是http的原因

    https://www.zjtest6.com/admin/api/menu haproxy 日志: Jun 24 13:23:02 localhost haproxy[23205]: 192.168 ...

  8. 第二章排错的工具:调试器Windbg(上)

    感谢博主 http://book.51cto.com/art/200711/59731.htm <Windows用户态程序高效排错>第二章主要介绍用户态调试相关的知识和工具.本文主要讲了排 ...

  9. jQuery EasyUI API 中文文档 - 菜单按钮(menubutton)

    <html> <head> <script src="jquery-easyui/jquery.min.js"></script> ...

  10. wikioi 1014 装箱问题

    来源:http://wikioi.com/problem/1014/ 1014 装箱问题 29人推荐 收藏 发题解 提交代码 报错 题目描写叙述 输入描写叙述 输出描写叙述 例子输入 例子输出 提示 ...