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

      

  • 相关阅读:
    C++学习9 this指针详解
    福建省第八届 Triangles
    UVA 11584 Partitioning by Palindromes
    POJ 2752 Seek the Name, Seek the Fame
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    HDU 2988 Dark roads(kruskal模板题)
    HDU 1385 Minimum Transport Cost
    HDU 2112 HDU Today
    HDU 1548 A strange lift(最短路&&bfs)
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1269.html
Copyright © 2011-2022 走看看