zoukankan      html  css  js  c++  java
  • BZOJ 1507 NOI2003 Editor Splay

    题目大意:

    1.将光标移动到某一位置
    2.在光标后插入一段字符串
    3.删除光标后的一段字符
    4.输出光标后的一段字符
    5.光标--
    6.光标++

    和1269非常像的一道题,只是弱多了

    几个问题须要注意:

    1.插入的字符串中间竟然会有回车!

    。没办法了,仅仅能逐个字符进行读入。一旦读到' '或者' '就又一次读入

    2.题目描写叙述中说Delete和Get操作后面一定会有足够的字符 纯属放P 连例子都没有足够的字符用来删除 所以删除时要和字符串长度取一个最小值

    然后就水水地过去了~

    30%达成 今天是不是能够歇息了0.0 妈蛋先把圆上的整点搞过去再说

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct abcd{
    	abcd *fa,*ls,*rs;
    	char c;
    	int siz;
    	bool rev_mark;
    	abcd (char C);
    	void Push_Up();
    }*null=new abcd(0),*root=null;
    abcd :: abcd(char C)
    {
    	fa=ls=rs=null;
    	c=C;
    	siz=C?1:0;
    	rev_mark=0;
    }
    void abcd :: Push_Up()
    {
    	siz=ls->siz+rs->siz+1;
    }
    void Zig(abcd *x)
    {
    	abcd *y=x->fa;
    	y->ls=x->rs;
    	x->rs->fa=y;
    	x->rs=y;
    	x->fa=y->fa;
    	if(y==y->fa->ls)
    		y->fa->ls=x;
    	else if(y==y->fa->rs)
    		y->fa->rs=x;
    	y->fa=x;
    	y->Push_Up();
    	if(y==root)
    		root=x;
    }
    void Zag(abcd *x)
    {
    	abcd *y=x->fa;
    	y->rs=x->ls;
    	x->ls->fa=y;
    	x->ls=y;
    	x->fa=y->fa;
    	if(y==y->fa->ls)
    		y->fa->ls=x;
    	else if(y==y->fa->rs)
    		y->fa->rs=x;
    	y->fa=x;
    	y->Push_Up();
    	if(y==root)
    		root=x;
    }
    void Splay(abcd *x,abcd *Tar)
    {
    	while(1)
    	{
    		abcd *y=x->fa,*z=y->fa;
    		if(y==Tar)
    			break ;
    		if(z==Tar)
    		{
    			if(x==y->ls)
    				Zig(x);
    			else
    				Zag(x);
    			break;
    		}
    		if(x==y->ls)
    		{
    			if(y==z->ls)
    				Zig(y);
    			Zig(x);
    		}
    		else
    		{
    			if(y==z->rs)
    				Zag(y);
    			Zag(x);
    		}
    	}
    	x->Push_Up();
    }
    void Find(abcd *x,int y,abcd *z)
    {
    	while(1)
    	{
    		if(y<=x->ls->siz)
    			x=x->ls;
    		else
    		{
    			y-=x->ls->siz;
    			if(y==1)
    				break;
    			y--;
    			x=x->rs;
    		}
    	}
    	Splay(x,z);
    }
    void Output(abcd *x)
    {
    	if(x==null)
    		return ;
    	Output(x->ls);
    	putchar(x->c);
    	Output(x->rs);
    }
    char s[1<<21];
    void Build_Tree(abcd *&x,int l,int r)
    {
    	if(l>r)
    		return ;
    	int mid=l+r>>1;
    	x=new abcd(s[mid]);
    	Build_Tree(x->ls,l,mid-1);
    	Build_Tree(x->rs,mid+1,r);
    	if(x->ls!=null)
    		x->ls->fa=x;
    	if(x->rs!=null)
    		x->rs->fa=x;
    	x->Push_Up();
    }
    int cursor,m;
    int main()
    {
    	int i,j,x;
    	char p[100];
    	cin>>m;
    	{
    		root=new abcd('
    ');
    		root->rs=new abcd('
    ');
    		root->rs->fa=root;
    		root->Push_Up();
    	}
    	for(i=1;i<=m;i++)
    	{
    		scanf("%s",p);
    		if(p[0]=='M')
    			scanf("%d",&cursor);
    		else if(p[0]=='I')
    		{
    			scanf("%d",&x);
    			for(j=0;j<x;j++)
    			{
    				do s[j]=getchar(); while(s[j]<32);
    			}
    			Find(root,cursor+1,null);
    			Find(root,cursor+2,root);
    			Build_Tree(root->rs->ls,0,x-1);
    			root->rs->ls->fa=root->rs;
    			root->rs->Push_Up();
    			root->Push_Up();
    		}
    		else if(p[0]=='D')
    		{
    			scanf("%d",&x);
    			Find(root,cursor+1,null);
    			Find(root,min(cursor+x+2,root->siz),root);
    			root->rs->ls=null;
    			root->rs->Push_Up();
    			root->Push_Up();
    		}
    		else if(p[0]=='G')
    		{
    			scanf("%d",&x);
    			Find(root,cursor+1,null);
    			Find(root,min(cursor+x+2,root->siz),root);
    			Output(root->rs->ls);
    			puts("");
    		}
    		else if(p[0]=='P')
    			cursor--;
    		else
    			cursor++;
    	}
    }
    


  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7115505.html
Copyright © 2011-2022 走看看