• AHOI2006 文本编辑器(BZOJ1269)


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1269

    1269: [AHOI2006]文本编辑器editor

    Time Limit: 10 Sec  Memory Limit: 162 MB

    Description

    这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格。光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文 本的某两个相邻字符之间。文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程序。如果这段文本为空,我们就说这个文本编辑器是空 的。 编写一个程序: 建立一个空的文本编辑器。 从输入文件中读入一些操作指令并执行。 对所有执行过的GET操作,将指定的内容写入输出文件。

    Input

    输入文件中第一行是指令条数N,以下是需要执行的N个操作。除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。

    Output

    依次对应输入文件中每条GET指令的输出,不得有任何多余的字符。

    Sample Input

    10
    Insert 13
    Balanced eert
    Move 2
    Delete 5
    Next
    Insert 7
    editor
    Move 0
    Get
    Move 11
    Rotate 4
    Get

    Sample Output

    B
    t

    HINT

    对输入数据我们有如下假定: MOVE操作不超过50 000个,INSERT、DELETE和ROTATE操作作的总个数不超过6 000,GET操作不超过20 000个,PREV和NEXT操作的总个数不超过20 000。 所有INSERT插入的字符数之和不超过2M(1M=1 024*1 024)。 DELETE操作、ROTATE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作不会把光标移动到非法位置。 输入文件没有错误。

    Source

    鸣谢seter重新制作数据

    这题是道不错的平衡树题。。就是初始时建树有些麻烦,这题用链式建树会方便。

    。。坑爹的是我没加读入优化交了TLE。。加了读入优化之后1368ms。。

    Codes:

      1 #include<set>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<algorithm>
      7 using namespace std;
      8 const int N = 1024 * 1024 * 2 + 10;
      9 #define fa(i) (T[i].p)
     10 #define L(i) (T[i].s[0])
     11 #define R(i) (T[i].s[1])
     12 #define Key (L(R(root)))
     13 #define Loc(i) (T[fa(i)].s[1]==i)
     14 #define For(i,n) for(int i=1;i<=n;i++)
     15 #define Rep(i,l,r) for(int i=l;i<=r;i++)
     16 #define Sets(a,b,c) {if(a) T[a].s[c] = b; if(b) fa(b) = a;}
     17 struct tnode{
     18     int s[2],p,size,rev;
     19     char v;
     20 }T[N];
     21 
     22 char op[10],str[N];
     23 int n,tot,len,root,cur;
     24 
     25 void Update(int i){
     26     T[i].size = T[L(i)].size + T[R(i)].size + 1;
     27 }
     28 
     29 void Pushdown(int i){
     30     if(T[i].rev){
     31         if(L(i)) T[L(i)].rev ^= 1;
     32         if(R(i)) T[R(i)].rev ^= 1;
     33         swap(L(i),R(i));
     34         T[i].rev = 0;
     35     }    
     36 }
     37 
     38 void Build(int l,int r,int p,int &i){
     39     if(l>r) return;
     40     T[i=++tot].p = p;T[i].size = 1;T[i].rev = 0;
     41     int m = (l+r)>>1;
     42     T[i].v = str[m];
     43     Build(l,m-1,i,L(i));Build(m+1,r,i,R(i));
     44     Update(i);
     45 }
     46 
     47 int Rank(int kth,int i){
     48     Pushdown(i);
     49     if(T[L(i)].size + 1 == kth)  return i;
     50     else if(T[L(i)].size >= kth) return Rank(kth,L(i));
     51     else                         return Rank(kth - T[L(i)].size - 1 , R(i));
     52 }
     53 
     54 void Rot(int x){
     55     int y = fa(x) , z = fa(y);
     56     int lx = Loc(x) , ly = Loc(y);
     57     Pushdown(y);Pushdown(x);
     58     Sets(y,T[x].s[!lx],lx);
     59     Sets(z,x,ly);
     60     Sets(x,y,!lx);
     61     Update(y);
     62 }
     63 
     64 void Splay(int i,int goal){
     65     while(fa(i)!=goal){
     66         if(fa(fa(i))!=goal) Rot(fa(i));
     67         Rot(i);
     68     }
     69     Update(i);
     70     if(!goal) root = i;
     71 }
     72 
     73 int read(){
     74     int num = 0; char ch = getchar();
     75     while(ch>'9'||ch<'0') ch = getchar();
     76     while(ch>='0'&&ch<='9'){
     77         num = num * 10 + ch - '0';
     78         ch = getchar();
     79     }
     80     return num;
     81 }
     82 
     83 int main(){
     84     n = read();
     85     T[root=++tot].p = 0;R(root)=++tot;T[R(root)].p = root;
     86     Update(R(root));Update(root);
     87     For(i,n){
     88         scanf("%s",&op);
     89         if(op[0]=='I'){
     90             len = read();
     91             gets(str);
     92             Splay(Rank(cur+1,root),0);
     93             Splay(Rank(cur+2,root),root);
     94             Build(0,len-1,R(root),Key);
     95             Update(R(root));Update(root);
     96         }else
     97         if(op[0]=='M'){
     98             len = read();cur = len;
     99         }else
    100         if(op[0]=='D'){
    101             len = read();
    102             Splay(Rank(cur+1,root),0);
    103             Splay(Rank(cur+len+2,root),root);
    104             T[Key].p = 0;T[R(root)].s[0] = 0;
    105             Update(R(root));Update(root);
    106         }else
    107         if(op[0]=='N') cur++;else
    108         if(op[0]=='P') cur--;else
    109         if(op[0]=='G'){
    110             Splay(Rank(cur+2,root),0);
    111             printf("%c
    ",T[root].v);
    112         }else
    113         if(op[0]=='R'){
    114             len = read();
    115             Splay(Rank(cur+1,root),0);
    116             Splay(Rank(cur+len+2,root),root);
    117             T[Key].rev ^= 1;
    118         }
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    21.09.12模拟 P2809 hzwer 爱折纸
    21.09.13模拟 保存名画
    21.09.13模拟赛 魔法传输
    21.09.13模拟 分割金币
    21.09.13模拟 友谊值
    21.09.10模拟 朗格拉日计数
    21.09.10模拟 雷神领域
    P4551 最长异或路径
    P2894 [USACO08FEB]Hotel G
    NOIP复习(总结套路)
  • 原文地址:https://www.cnblogs.com/zjdx1998/p/3877903.html
Copyright © 2020-2023  润新知