zoukankan      html  css  js  c++  java
  • BZOJ1507 [NOI2003]Editor

    BZOJ1507 [NOI2003]Editor

    Description

    很久很久以前,DOS3.x的程序员们开始对 EDLINEDLIN 感到厌倦。
    于是,人们开始纷纷改用自己写的文本编辑器??
    多年之后,出于偶然的机会,小明找到了当时的一个编辑软件。进行了一些简单的测试后,
    小明惊奇地发现:那个软件每秒能够进行上万次编辑操作(当然,你不能手工进行这样的测试) !
    于是,小明废寝忘食地想做一个同样的东西出来。你能帮助他吗?
    为了明确目标,小明对“文本编辑器”做了一个抽象的定义:
    文本:由 0 个或多个 ASCII 码在闭区间[3232 , 126126 ]内的字符构成的序列。
    光标:在一段文本中用于指示位置的标记,可以位于文本首部,文本尾部或文本的某两个字符之间。
    文本编辑器:由一段文本和该文本中的一个光标组成的,支持如下操作的数据结构。
    如果这段文本为空,我们就说这个文本编辑器是空的。
    操作名称 输入文件中的格式     功能
    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 操作,将指定的内容写入输出文件。

    Input

    第一行是指令条数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

    每行依次对应输入文件中每条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
    题解Here!
    额,又是这种恶心Splay题,已经有一道题的经验了——BZOJ1500: [NOI2005]维修数列
    所以这题就跟那个题差不多,就不详细讲解了。
    真的调试不出来就看代码吧。
    附上代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #define MAXN 3000010
    using namespace std;
    queue<int> point;
    int mouse=0,root=0,size=0;
    char val[MAXN];
    struct node{
        int f,s,son[2];
        char v;
    }a[MAXN];
    inline int read(){
        int date=0,w=1;char c=0;
        while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
        while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
        return date*w;
    }
    inline void clean(int rt){
    	a[rt].son[0]=a[rt].son[1]=a[rt].f=a[rt].s=a[rt].v=0;
    }
    inline void pushup(int rt){
        if(!rt)return;
        a[rt].s=1;
    	if(a[rt].son[0])a[rt].s+=a[a[rt].son[0]].s;
    	if(a[rt].son[1])a[rt].s+=a[a[rt].son[1]].s;
    }
    inline void turn(int rt,int k){
    	int x=a[rt].f,y=a[x].f;
    	a[x].son[k^1]=a[rt].son[k];
    	if(a[rt].son[k])a[a[rt].son[k]].f=x;
    	a[rt].f=y;
    	if(y)a[y].son[a[y].son[1]==x]=rt;
    	a[x].f=rt;
    	a[rt].son[k]=x;
    	pushup(x);pushup(rt);
    }
    void splay(int rt,int ancestry){
    	while(a[rt].f!=ancestry){
    		int x=a[rt].f,y=a[x].f;
    		if(y==ancestry)turn(rt,a[x].son[0]==rt);
    		else{
    			int k=a[y].son[0]==x?1:0;
    			if(a[x].son[k]==rt){turn(rt,k^1);turn(rt,k);}
    			else{turn(x,k);turn(rt,k);}
    		}
    	}
    	if(ancestry==0)root=rt;
    }
    inline int newnode(char c){
        int rt;
        if(point.empty())rt=++size;
        else{
        	rt=point.front();
        	point.pop();
        }
        a[rt].son[0]=a[rt].son[1]=0;
        a[rt].v=c;a[rt].s=1;
        return rt;
    }
    int buildtree(int l,int r){
        if(l>r)return 0;
        int mid=l+r>>1,lson=0,rson=0;
        lson=buildtree(l,mid-1);
        int rt=newnode(val[mid]);
        rson=buildtree(mid+1,r);
        a[rt].son[0]=lson;
        a[rt].son[1]=rson;
        if(lson)a[lson].f=rt;
        if(rson)a[rson].f=rt;
        pushup(rt);
        return rt;
    }
    int kth(int rt,int k){
    	if(a[rt].s<k)return 0;
    	while(1){
    		int y=a[rt].son[0];
    		if(k>a[y].s+1){
    			k-=a[y].s+1;
    			rt=a[rt].son[1];
    		}
    		else if(k<=a[y].s)rt=y;
    		else return rt;
    	}
    }
    inline void insert(int rt,int k){
        int front=kth(rt,mouse+1),next=kth(rt,mouse+2),q=buildtree(1,k);
        splay(front,0);splay(next,front);
        a[next].son[0]=q;a[q].f=next;
        pushup(next);pushup(front);
    }
    void delete_tree(int rt){
    	if(!rt)return;
    	point.push(rt);
    	if(a[rt].son[0])delete_tree(a[rt].son[0]);
    	if(a[rt].son[1])delete_tree(a[rt].son[1]);
    	clean(rt);
    }
    inline void remove(int rt,int k){
    	int front=kth(rt,mouse+1),next=kth(rt,mouse+k+2),q;
    	splay(front,0);
    	splay(next,front);
    	q=a[next].son[0];
    	delete_tree(q);
    	a[next].son[0]=0;
    	pushup(next);pushup(front);
    }
    void print(int rt){
    	if(!rt)return;
    	if(a[rt].son[0])print(a[rt].son[0]);
    	if(a[rt].v!=0)printf("%c",a[rt].v);
    	if(a[rt].son[1])print(a[rt].son[1]);
    }
    inline void get(int rt,int k){
    	int front=kth(rt,mouse+1),next=kth(rt,mouse+k+2),q;
    	splay(front,0);splay(next,front);
    	q=a[next].son[0];
    	print(q);
    	printf("
    ");
    }
    void work(){
        int x,y,k,t=read();
        char ch[10];
        while(t--){
            scanf("%s",ch);
            switch(ch[0]){
                case 'M':mouse=read();break;
                case 'I':{
                    k=read();
                    for(int j=1;j<=k;j++){
                    	char c=getchar();
                    	while(c=='
    '||c=='
    ')c=getchar();
                    	val[j]=c;
                    }
                    insert(root,k);
                    break;
                }
                case 'D':{
                	k=read();
                	remove(root,k);
                    break;
                }
                case 'G':{
                	k=read();
                	get(root,k);
                    break;
                }
                case 'P':mouse--;break;
                case 'N':mouse++;break;
            }
        }
    }
    void init(){
        val[1]=val[2]=0;
        root=buildtree(1,2);
    }
    int main(){
        init();
        work();
        return 0;
    }
    
  • 相关阅读:
    AX 2012 Security Framework
    The new concept 'Model' in AX 2012
    How to debug the SSRS report in AX 2012
    Using The 'Report Data Provider' As The Data Source For AX 2012 SSRS Report
    Deploy SSRS Report In AX 2012
    AX 2012 SSRS Report Data Source Type
    《Taurus Database: How to be Fast, Available, and Frugal in the Cloud》阅读笔记
    图分析理论 大纲小结
    一文快速了解Posix IO 缓冲
    #转载备忘# Linux程序调试工具
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9074513.html
Copyright © 2011-2022 走看看