BZOJ1507 [NOI2003]Editor

AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1507

【分析】

  据说打完维修数列,什么数据结构题都是浮云了...这题似乎就是一个简化版咯。

  这题的要求都和字母的值无关,而是与字母在序列中的位置有关...所以应当用位置关系建树的方法啦[就是每次找第k个位置就是这个节点的左边有k-1个节点]

  首先预处理出两个虚拟节点作为开头和结尾[这个也是区间操作的比较基础的哦...]。

  每次的添加就是找到光标和光标的下一个组成的区间,然后接在下一个的左子树上[联系之前的区间的做法...]

  删除就是找到要删除的区间就好了...不过维修数列的心理阴影...我还是将节点回收了一下[会慢些...]。

  输出的话也是找到区间然后输出中序遍历。

  对于光标的操作直接设一个全局变量作为光标位置就好。

  

  本题有一个坑点...就是“所有INSERT插入的字符数之和不超过2M(1M=1024*1024)”很可能一个INSERT就输进来2000000个字符哦....所以要开这么大。

  [不过笔者偷偷瞄了数据只有1500000...]

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=1500010;

struct Node{
    int ch[2],f;
    int sz;
    char cc;
}s[maxn];

int n,gb,rt;
int tb[maxn],cot2,cot1;
char ord[15],ch[maxn];

void update(int x){
    s[x].sz=s[s[x].ch[0]].sz+s[s[x].ch[1]].sz+1;
}

void Rotate(int x,int k){
    int y=s[x].f;s[x].f=s[y].f;
    if(s[y].f)    s[s[y].f].ch[y==s[s[y].f].ch[1]]=x;
    s[y].ch[k]=s[x].ch[k^1];
    if(s[x].ch[k^1]) s[s[x].ch[k^1]].f=y;
    s[y].f=x,s[x].ch[k^1]=y;
    update(y),update(x);
}

void Splay(int x,int gf){
    int y;
    while(s[x].f!=gf){
        y=s[x].f;
        if(s[y].f==gf) Rotate(x,x==s[y].ch[1]);
        else{int z=s[y].f;
            if(y==s[z].ch[0]){if(x==s[y].ch[0]) Rotate(y,0),Rotate(x,0);else Rotate(x,1),Rotate(x,0);}
            else {if(x==s[y].ch[1]) Rotate(y,1),Rotate(x,1);else Rotate(x,0),Rotate(x,1);}
        }
    }
    if(!gf) rt=x;
}

int Find(int k){
    int p=rt;
    while(p){
        if(k<=s[s[p].ch[0]].sz) p=s[p].ch[0];
        else{
            k-=s[s[p].ch[0]].sz;
            if(k==1) return p;
            k--;p=s[p].ch[1];
        }
    }
}

int New_Node(){
    int x;
    if(cot2) x=tb[cot2--];
    else x=++cot1;
    s[x].sz=1;
    s[x].ch[0]=s[x].ch[1]=0;
    return x;
}

int build(int l,int r){
    if(l>r) return 0;
    int mid=(l+r)>>1,x=New_Node();
    s[x].ch[0]=build(l,mid-1);
    s[x].ch[1]=build(mid+1,r);
    s[x].cc=ch[mid];
    if(s[x].ch[0]) s[s[x].ch[0]].f=x;
    if(s[x].ch[1]) s[s[x].ch[1]].f=x;
    update(x);
    return x;
}

void Del(int x){
    if(!x) return;tb[++cot2]=x;
    Del(s[x].ch[0]),Del(s[x].ch[1]);
}

void Print(int x){
    if(!x) return ;
    Print(s[x].ch[0]);
    if(s[x].cc)
        printf("%c",s[x].cc);
    Print(s[x].ch[1]);
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("1507.in","r",stdin);
    freopen("1507.out","w",stdout);
#endif
    int x,k,t,t1;

    gb=rt=New_Node();
    s[rt].ch[1]=New_Node();
    s[2].f=rt;
    update(rt);

    scanf("%d",&n);
    while(n--){
        scanf("%s",ord);
        //Print(rt);putchar(‘\n‘);
        if(strcmp(ord,"Move")==0)
            scanf("%d",&x),gb=x+1;
        else if(strcmp(ord,"Insert")==0){
            scanf("%d",&x);
            for(int i=1;i<=x;i++){
                scanf("%c",&ch[i]);
                if(ch[i]==‘\n‘) i--;
            }
            k=build(1,x);
            t=Find(gb);
            Splay(t,0);
            if(s[rt].ch[1]){
                t1=Find(gb+1);Splay(t1,rt);
                s[k].f=t1,s[t1].ch[0]=k;
                update(t1),update(rt);
            }
            else
                s[k].f=rt,s[rt].ch[1]=k,update(rt);
        }
        else if(strcmp(ord,"Delete")==0){
            scanf("%d",&x);
            t=Find(gb);t1=Find(gb+x+1);
            Splay(t,0),Splay(t1,t);
            Del(s[t1].ch[0]);
            s[t1].ch[0]=0;
            update(t1),update(t);
        }
        else if(strcmp(ord,"Get")==0){
            scanf("%d",&x);
            t=Find(gb),t1=Find(gb+x+1);
            Splay(t,0),Splay(t1,t);
            Print(s[t1].ch[0]);
            putchar(‘\n‘);
        }
        else if(strcmp(ord,"Prev")==0) gb--;
        else gb++;
    }

    return 0;
}

时间: 2024-12-25 00:29:32

BZOJ1507 [NOI2003]Editor的相关文章

BZOI 1507 [NOI2003] Editor

Background After trying to solve problem EDIT1(Editor) and being ****ed by Brainf**k, Blue Mary decided to set another difficult problem about editor. Description Some definations: Text: It's a sequence that consists characters whose ASCII code is in

1507: [NOI2003]Editor(块状链表)

1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 4157  Solved: 1677[Submit][Status][Discuss] Description Input 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例). 除了回车符之外,输入文件的所有字

BZOJ 1507 NOI2003 Editor Splay

题目大意: 1.将光标移动到某一位置 2.在光标后插入一段字符串 3.删除光标后的一段字符 4.输出光标后的一段字符 5.光标-- 6.光标++ 和1269很像的一道题,不过弱多了 几个问题需要注意: 1.插入的字符串中间居然会有回车!!没办法了,只能逐个字符进行读入,一旦读到'\n'或者'\r'就重新读入 2.题目描述中说Delete和Get操作后面一定会有足够的字符 纯属放P 连样例都没有足够的字符用来删除 所以删除时要和字符串长度取一个最小值 然后就水水地过去了~ 30%达成 今天是不是可

bzoj 1507: [NOI2003]Editor

1 #include<cstdio> 2 #include<iostream> 3 #include<ext/rope> 4 using namespace std; 5 using namespace __gnu_cxx; 6 crope list; 7 int n,now; 8 char ch[10],ch1[3000005]; 9 int main() 10 { 11 scanf("%d",&n); 12 for(int i=1;i&l

[NOI2003]Editor(块状链表)

传送门 看了看块状链表,就是数组和链表的合体. 看上去好高大尚,思想也很简单. 但是发现代码量也不是很小,而且代码理解起来也是费尽得很,倒不如splay用起来顺手. 在加上适用范围貌似不是特别广,所以只把模板贴在这,只当了解思想,暂时先不使用.(也不会用啊) 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 using namespace std;

NOI2003 文本编辑器editor

1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 1908  Solved: 738[Submit][Status] Description Input 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例). 除了回车符之外,输入文件的所有字符的ASCII码都在

7、8月刷题总结

准备开学了囧,7.8月刷题记录,以后好来复习,并且还要好好总结! 数据结构: splay: [BZOJ]1503: [NOI2004]郁闷的出纳员(Splay) [BZOJ]1269: [AHOI2006]文本编辑器editor(Splay) [BZOJ]1507: [NOI2003]Editor(Splay) treap: [BZOJ]1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心) [BZOJ]3224: Tyvj

博客开更!!

好颓啊!!  做题好慢!! 各种错误!! 1014: [JSOI2008]火星人prefix 额 splay没啥说的 字符串hash蒟蒻不会啊 搞半天才懂 好玄学啊 unsigned的自然溢出也是玄学啊 (话说我 int的自然溢出也A了smg?? 1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std

小结:平衡树

概要: 平衡树大概是最常用的高级数据结构了,而treap用来进行一般的信息维护,splay用来进行高级的信息维护(比如区间操作.lct等)(map.set党自重QAQ). 技巧及注意: 细节十分多. treap中如果设小根堆的话(最好设小根堆),null的重量要设置为inf. 平衡树中的重复元素两种处理方法,看情况使用. 平衡树中的rank和select要和上一种注意事项结合起来,多想想. splay中如果写lct要特判根.treap很多地方要传指针引用,splay完全不必.写好后最好手造几组h