• BZOJ_1507_Editor_[NOI2003]_(Splay)


    描述


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

    简单区间操作的模板题

    1507: [NOI2003]Editor

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 3092  Solved: 1244
    [Submit][Status][Discuss]

    Description

    Input

    输 入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作。其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例)。 除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。 这里我们有如下假定:  MOVE操作不超过50000个,INSERT和DELETE操作的总个数不超过4000,PREV和NEXT操作的总个数不超过200000。  所有INSERT插入的字符数之和不超过2M(1M=1024*1024),正确的输出文件长度不超过3M字节。  DELETE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作必然不会试图把光标移动到非法位置。  输入文件没有错误。 对C++选手的提示:经测试,最大的测试数据使用fstream进行输入有可能会比使用stdio慢约1秒。

    Output

    输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。

    Sample Input

    15
    Insert 26
    abcdefghijklmnop
    qrstuv wxy
    Move 15
    Delete 11
    Move 5
    Insert 1
    ^
    Next
    Insert 1
    _
    Next
    Next
    Insert 4
    ./.
    Get 4
    Prev
    Insert 1
    ^
    Move 0
    Get 22

    Sample Output

    ./.
    abcde^_^f./.ghijklmno

    HINT

    Source

    分析


    和BZOJ_1269很像,而且更简单.

    首先加入一个起始字符和尾字符(因为我们解决问题的办法都是在两个区间之间进行的).

    操作:

    1.插入:把at转到根节点,把at+1转到根节点的右儿子,然后在at+1的左儿子处插入即可.

    2.移动:直接输入到at即可.

    3.删除:把at转到根节点,把at+n+1转到根节点的右儿子,然后把at+n+1的左儿子直接改成null即可.

    4.&5.移动光标就at--,at++即可.

      1 #include <cstdio>
      2 #include <algorithm>
      3 using namespace std;
      4  
      5 const int maxn=(2<<21)+5,oo=~0u>>1;
      6  
      7 int n,x,at,cur;
      8 char str[maxn],s[10];
      9  
     10 struct Splay{
     11     struct node{
     12         node* ch[2],* pa;
     13         char v; int s;
     14         node(int v,node* t):v(v){ ch[0]=ch[1]=pa=t; s=1; }
     15         bool d(){ return pa->ch[1]==this; }
     16         void setc(node* t,bool d){ ch[d]=t; t->pa=this; }
     17         void push_up(){ s=ch[0]->s+ch[1]->s+1; }
     18     }*root,*null;
     19     Splay(){
     20         null=new node('',NULL); null->s=0;
     21         root=new node('',null);
     22         node* t=new node('',null);
     23         root->setc(t,1);
     24         root->push_up();
     25     }
     26     void rot(node* o){
     27         node* pa=o->pa; bool d=o->d();
     28         pa->pa->setc(o,pa->d());
     29         pa->setc(o->ch[!d],d);
     30         o->setc(pa,!d);
     31         pa->push_up();
     32         if(pa==root) root=o;
     33     }
     34     void splay(node* o,node* pa){
     35         while(o->pa!=pa){
     36             if(o->pa->pa==pa) rot(o);
     37             else o->d()==o->pa->d()?(rot(o->pa),rot(o)):(rot(o),rot(o));
     38         }
     39         o->push_up();
     40     }
     41     node* kth(int k){
     42         k++;
     43         for(node* t=root;;){
     44             int s=t->ch[0]->s+1;
     45             if(s==k) return t;
     46             if(k>s) k-=s,t=t->ch[1];
     47             else t=t->ch[0];
     48         }
     49     }
     50     node* build(int l,int r){
     51         if(l==r) return new node(str[l],null);
     52         if(l>r) return null;
     53         int m=l+(r-l)/2;
     54         node* t=new node(str[m],null);
     55         t->setc(build(l,m-1),0);
     56         t->setc(build(m+1,r),1);
     57         t->push_up();
     58         return t;
     59     }
     60     node* find(int l,int r){
     61         node* L=kth(l); splay(L,null);
     62         node* R=kth(r); splay(R,L);
     63         return R;
     64     }
     65     void insert(int at,int cur){
     66         node* t=find(at,at+1);
     67         t->setc(build(0,cur),0); t->push_up();
     68         splay(t,null);
     69     }
     70     void remove(int at,int n){
     71         node* t=find(at,at+n+1);
     72         t->setc(null,0); t->push_up();
     73         splay(t,null);
     74     }
     75     void print(node* o){
     76         if(o==null) return;
     77         print(o->ch[0]);
     78         printf("%c",o->v);
     79         print(o->ch[1]);
     80     }
     81     void print(int at,int n){
     82         node* t=find(at,at+n+1);
     83         print(t->ch[0]);
     84         printf("
    ");
     85     }
     86 }tree;
     87  
     88 int main(){
     89     scanf("%d",&n);
     90     while(n--){
     91         scanf("%s",s);
     92         if(s[0]=='I'){
     93             cur=0;
     94             scanf("%d",&x);
     95             while(x--){
     96                 while(str[cur]=getchar(),str[cur]=='
    ');
     97                 cur++;
     98             }
     99             cur--;
    100             tree.insert(at,cur);
    101         }
    102         else if(s[0]=='M') scanf("%d",&at);
    103         else if(s[0]=='D'){
    104             scanf("%d",&x);
    105             tree.remove(at,x);
    106         }
    107         else if(s[0]=='G'){
    108             scanf("%d",&x);
    109             tree.print(at,x);
    110         }
    111         else if(s[0]=='P') at--;
    112         else at++;
    113     }
    114     return 0;
    115 }
    View Code


     

  • 相关阅读:
    面试常见题型
    docker的安装及基本使用
    redis缓存的使用
    ab压测工具
    redis分布式锁的使用
    webSocket的基本使用
    递归、os.walk、内置函数、lambda、hashlib模块、md5加密、python安装第三方模块、操作mysql数据库
    【Apache】Apache ab压力测试工具Window下载和用法详解
    函数默认值参数、全局变量、深拷贝、可变参数、关键字参数、json模块使用、time模块操作
    python的文件操作1,监控日志联系、读取大文件、修改文件、集合、元组、random模块以及函数初识
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5499679.html
Copyright © 2020-2023  润新知