• BZOJ1269 [AHOI2006]文本编辑器editor splay


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ1269


    题意概括

      你要搞一个文本编辑器。

      主要支持一下操作:

      插入字符串、删除字符串、区间字符串翻转、输出光标后的一个字符。

      详细见原题。


    题解

      splay板子题。

      一开始我是一个一个字符弄到splay里面去,结果Tle了。

      所以,我们要一段一段的插入。删除也同理,详见代码


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int MaxL=2100000;
    char str[MaxL];
    struct Splay{
    	int root,cnt,fa[MaxL],son[MaxL][2],size[MaxL],val[MaxL],rev[MaxL];
    	void clear(){
    		root=cnt=0;
    		memset(size,0,sizeof size);
    		memset(son,0,sizeof son);
    		memset(val,0,sizeof val);
    		memset(rev,0,sizeof rev);
    		memset(fa,0,sizeof fa);
    	}
    	void print(){
    		puts("Splay.Print_________________");
    		printf("root=%d
    ",root);
    		for (int i=1;i<=cnt;i++)
    			printf("%d:fa=%d,son=(%d,%d),size=%d,val=%c,rev=%d
    "
    			,i,fa[i],son[i][0],son[i][1],size[i],(char)val[i],rev[i]);
    		puts("Splay.Print_Over============");
    	}
    	void dfs(int rt){
    		pushdown(rt);
    		if (son[rt][0])
    			dfs(son[rt][0]);
    		printf("%c",val[rt]);
    		if (son[rt][1])
    			dfs(son[rt][1]);
    	}
    	void printstr(){
    		dfs(root);puts("");
    	}
    	void pushup(int x){size[x]=size[son[x][0]]+size[son[x][1]]+1;}
    	void pushrev(int x){
    		if (!x)
    			return;
    		rev[x]^=1;
    		swap(son[x][0],son[x][1]);
    	}
    	void pushdown(int x){
    		if (rev[x]){
    			rev[x]=0;
    			pushrev(son[x][0]);
    			pushrev(son[x][1]);
    		}
    	}
    	void pushadd(int x){
    		if (fa[x])
    			pushadd(fa[x]);
    		pushdown(x);
    	}
    	int wson(int x){return son[fa[x]][1]==x;}
    	void rotate(int x){
    		if (!fa[x])
    			return;
    		int y=fa[x],z=fa[y],L=wson(x),R=L^1;
    		if (z)
    			son[z][wson(y)]=x;
    		fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
    		son[y][L]=son[x][R],son[x][R]=y;
    		pushup(y);
    		pushup(x);
    	}
    	void splay(int x,int k){
    		pushadd(x);
    		if (k==0)
    			root=x;
    		while (fa[x]!=k){
    			int y=fa[x],z=fa[y];
    			if (z!=k)
    				rotate(wson(x)==wson(y)?y:x);
    			rotate(x);
    		}
    	}
    	void splay(int x){
    		splay(x,0);
    	}
    	void add(int &x,int pre,int befo,int v){
    		if (!x){
    			val[x=++cnt]=v,fa[x]=pre,size[x]=1;
    			son[x][0]=son[x][1]=rev[x]=0;
    			splay(x);
    			return;
    		}
    		pushdown(x);
    		size[x]++;
    		if (size[son[x][0]]>=befo)
    			add(son[x][0],x,befo,v);
    		else
    			add(son[x][1],x,befo-size[son[x][0]]-1,v);
        }
        void add(int befo,int v){add(root,0,befo,v);}
    	void build(int &x,int pre,int L,int R){
    		if (L>R)
    			return;
    		int mid=(L+R)>>1;
    		fa[x=++cnt]=pre,val[x]=str[mid],rev[x]=0,size[x]=1,son[x][0]=son[x][1]=0;
    		build(son[x][0],x,L,mid-1);
    		build(son[x][1],x,mid+1,R);
    		pushup(x);
    	}
    	int findkth(int x,int k){
    		pushdown(x);
    		if (k==size[son[x][0]]+1)
    			return x;
    		if (k<=size[son[x][0]])
    			return findkth(son[x][0],k);
    		else
    			return findkth(son[x][1],k-size[son[x][0]]-1);
    	}
    	int findkth(int k){return findkth(root,k);}
    	int findL(int x){
    		pushdown(x);
    		if (son[x][0])
    			return findL(son[x][0]);
    		return x;
    	}
    	int findR(int x){
    		pushdown(x);
    		if (son[x][1])
    			return findR(son[x][1]);
    		return x;
    	}
    	void erase(int L,int R){
    		splay(findkth(L-1));
    		splay(findkth(R+1),root);
    		fa[son[son[root][1]][0]]=0;
    		son[son[root][1]][0]=0;
    		pushup(son[root][1]);
    		pushup(root);
    	}
    }s;
    int n,p;
    int main(){
    	scanf("%d",&n);
    	s.clear();
    	s.add(1,'#'),s.add(1,'#');
    	p=0;
    	for (int c=1;c<=n;c++){
    //		s.print();
    //		s.printstr();
    		char op[10];
    		int a;
    		scanf("%s",op);
    		if (op[0]=='M')
    			scanf("%d",&p);
    		else if (op[0]=='I'){
    			scanf("%d%*c",&a);
    			gets(str+1);
    			s.splay(s.findkth(p+1));
    			s.splay(s.findkth(p+2),s.root);
    			s.build(s.son[s.son[s.root][1]][0],s.son[s.root][1],1,a);
    		}
    		else if (op[0]=='D'){
    			scanf("%d",&a);
    			s.erase(p+2,p+1+a);
    		}
    		else if (op[0]=='R'){
    			scanf("%d",&a);
    			s.splay(s.findkth(p+1));
    			s.splay(s.findkth(p+a+2),s.findkth(p+1));
    			s.pushrev(s.son[s.son[s.root][1]][0]);
    		}
    		else if (op[0]=='G')
    			printf("%c
    ",(char)s.val[s.findkth(p+2)]);
    		else if (op[0]=='P')
    			p--;
    		else if (op[0]=='N')
    			p++;
    	}
    	return 0;
    }
    /*
    10
    Insert 13
    Balanced eert
    Move 2
    Delete 5
    Next
    Insert 7
     editor
    Move 0
    Get
    Move 11
    Rotate 4
    Get
    */
    

      

  • 相关阅读:
    Linux 文件的软连接和硬连接
    URLOS发布NFS文件加速功能,可有效提升NFS小文件读取性能
    Vue底层学习3——手撸发布订阅模式
    Vue底层学习2——手撸数据响应化
    Vue底层学习1——原理解析
    rest api测试工具frisbyjs
    git ignore 微软临时文件(~$xxx.xlsx)
    数据虚拟化-基础概念
    elasticsearch移除映射类型(mapping type)
    activemq Virtual Destinations 虚拟目的地
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1269.html
Copyright © 2020-2023  润新知