zoukankan      html  css  js  c++  java
  • 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


     

  • 相关阅读:
    一些你可能用到的代码
    iOS 键盘下去的方法
    iOS设计模式汇总
    随笔
    Spring cloud config 分布式配置中心 (三) 总结
    Spring cloud config 分布式配置中心(二) 客户端
    Spring cloud config 分布式配置中心(一) 服务端
    jdbcUrl is required with driverClassName spring boot 2.0版本
    JpaRepository接口找不到 spring boot 项目
    解决IntelliJ “Initialization failed for 'https://start.spring.io'
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5499679.html
Copyright © 2011-2022 走看看