• 洛谷 P4008 [NOI2003]文本编辑器 解题报告


    P4008 [NOI2003]文本编辑器

    题目描述

    很久很久以前,(DOS3.x)的程序员们开始对 (EDLIN) 感到厌倦。于是,人们开始纷纷改用自己写的文本编辑器⋯⋯

    多年之后,出于偶然的机会,小明找到了当时的一个编辑软件。进行了一些简单的测试后,小明惊奇地发现:那个软件每秒能够进行上万次编辑操作(当然,你不能手工进行这样的测试) !于是,小明废寝忘食地想做一个同样的东西出来。你能帮助他吗?

    为了明确目标,小明对“文本编辑器”做了一个抽象的定义:

    文本:由 (0) 个或多个 ASCII 码在闭区间([32,126])内的字符构成的序列。

    光标:在一段文本中用于指示位置的标记,可以位于文本首部,文本尾部或文本的某两个字符之间。

    文本编辑器:由一段文本和该文本中的一个光标组成的,支持如下操作的数据结构。如果这段文本为空,我们就说这个文本编辑器是空的。

    操作名称 输入文件中的格式 功能
    (MOVE(k)) Move k 将光标移动到第k个字符之后,如果k=0,将光标移到文本开头
    (INSERT(n,s)) Insert n s 在光标处插入长度为n的字符串s,光标位置不变n≥1
    (DELETE(n)) Delete n 删除光标后的n个字符,光标位置不变,n ≥ 1
    (GET(n)) Get n 输出光标后的n个字符,光标位置不变,n ≥ 1
    (PREV()) Prev 光标前移一个字符
    (NEXT()) Next 光标后移一个字符

    你的任务是:

    建立一个空的文本编辑器。

    从输入文件中读入一些操作并执行。

    对所有执行过的 GET 操作,将指定的内容写入输出文件。

    输入输出格式

    输入格式:

    输入文件 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 秒。*

    输出格式:

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


    话说第一次见着这题是要用块状链表来着,今天不知道为什么就拿平衡树水了过去

    感觉还是比较卡时间的

    所以我们对于插入删除以及输出最好做到(O(logn+S)),而不是(O(lognS))
    (这里我对插入偷懒了emm
    (n)为当前树的大小,(s)为操作的字符串长度


    Code:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #define ls ch[now][0]
    #define rs ch[now][1]
    const int N=1e6+10;
    int ch[N][2],typ[N],val[N],siz[N],tot,root,t,pos,cnt,len;
    char opt[12];
    void updata(int now){siz[now]=siz[ls]+siz[rs]+1;}
    void split(int now,int k,int &x,int &y)
    {
        if(!now) {x=y=0;return;}
        if(siz[ls]+1<=k)
            x=now,split(rs,k-siz[ls]-1,rs,y);
        else if(siz[ls]>=k)
            y=now,split(ls,k,x,ls);
        updata(now);
    }
    int Merge(int x,int y)
    {
        if(!x||!y) return x+y;
        if(val[x]<val[y])
        {
            ch[x][1]=Merge(ch[x][1],y);
            updata(x);
            return x;
        }
        else
        {
            ch[y][0]=Merge(x,ch[y][0]);
            updata(y);
            return y;
        }
    }
    int New(int asc)
    {
        val[++tot]=rand(),typ[tot]=asc,siz[tot]=1;
        return tot;
    }
    void Insert(int asc)
    {
        int x,y;
        split(root,pos,x,y);
        root=Merge(x,Merge(New(asc),y));
        ++pos;
    }
    void extrack()
    {
        scanf("%d",&cnt);
        int x,y,z;
        split(root,pos,x,y);
        split(y,cnt,z,y);
        root=Merge(x,y);
    }
    void dfs(int now)
    {
        if(!now) return;
        dfs(ls);
        printf("%c",typ[now]);
        dfs(rs);
    }
    void out()
    {
        scanf("%d",&cnt);
        int x,y,z;
        split(root,pos,x,y);
        split(y,cnt,z,y);
        dfs(z);printf("
    ");
        root=Merge(x,Merge(z,y));
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",opt);
            if(opt[0]=='M') scanf("%d",&pos);
            else if(opt[0]=='I')
            {
                scanf("%d",&len);
                char c;int lpos=pos;
                while(len--)
                {
                    c=getchar();
                    while(c<32||c>126||c=='
    ') c=getchar();
                    Insert(c);
                }
                pos=lpos;
            }
            else if(opt[0]=='D') extrack();
            else if(opt[0]=='G') out();
            else if(opt[0]=='P') --pos;
            else ++pos;
        }
        return 0;
    }
    
    

    2018.9.3

  • 相关阅读:
    Android 2.2 r1 API 中文文档系列(11) —— RadioButton
    Android API 中文 (15) —— GridView
    Android 中文 API (16) —— AnalogClock
    Android2.2 API 中文文档系列(7) —— ImageButton
    Android2.2 API 中文文档系列(6) —— ImageView
    Android 2.2 r1 API 中文文档系列(12) —— Button
    Android2.2 API 中文文档系列(8) —— QuickContactBadge
    [Android1.5]TextView跑马灯效果
    [Android1.5]ActivityManager: [1] Killed am start n
    Android API 中文(14) —— ViewStub
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9580621.html
Copyright © 2020-2023  润新知