• 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('
    ');
            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]=='
    ') 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('
    ');
            }
            else if(strcmp(ord,"Prev")==0) gb--;
            else gb++;
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    原型模式 prototype
    OOAD之单例模式Singleton的6种写法
    OOAD之创建型模式之工厂模式
    OOAD之面向对象设计原则
    第一章 面向对象软件工程与UML
    Oracle数据库之PL/SQL触发器
    Oracle数据库之开发PL/SQL子程序和包
    Oracle数据库中的分页--rownum
    Oracle数据库之FORALL与BULK COLLECT语句
    Oracle数据库 中的基础的一些语法结构
  • 原文地址:https://www.cnblogs.com/Robert-Yuan/p/5090233.html
Copyright © 2020-2023  润新知