码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4286 Data Handler

时间:2014-07-20 22:12:53      阅读:337      评论:0      收藏:0      [点我收藏+]

标签:hdu   数据结构   

题意:

n个数字一开始排成一串  有两个指针L和R  指向了这串数字的一个区间的端点  现在有7种操作

1、使一个指针左移

2、使一个指针右移

3、在L后插入一个数字X

4、在R前插入一个数字X

5、删除L所指元素

6、删除R所指元素

7、翻转[L,R]区间

问  m次操作后  整串数字是什么样的


思路:

splay经典维护区间的操作  区间更新(翻转操作)  删除节点  插入节点

和 http://blog.csdn.net/houserabbit/article/details/37901199 这道Sort的题目类似  有区间翻转一定要注意down的操作


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
#define keytree ch[ch[root][1]][0]
#define L(x) ch[x][0]
#define R(x) ch[x][1]
#define N 1000100

int t,n,m,tot,root;
int a[N],ch[N][2],pre[N],size[N],val[N],rev[N];

void newnode(int &u,int fa,int w)
{
	u=++tot;
	L(u)=R(u)=0;
	pre[u]=fa;
	size[u]=1;
	val[u]=w;
	rev[u]=0;
}

void up(int u)
{
	size[u]=size[L(u)]+size[R(u)]+1;
}

void down(int u)
{
	if(rev[u])
	{
		rev[L(u)]^=1;
		rev[R(u)]^=1;
		rev[u]=0;
		swap(L(u),R(u));
	}
}

void rotate(int u,int kind)
{
	int fa=pre[u];
	down(fa);
	down(u);
	ch[fa][!kind]=ch[u][kind];
	pre[ch[u][kind]]=fa;
	if(pre[fa]) ch[pre[fa]][ch[pre[fa]][1]==fa]=u;
	pre[u]=pre[fa];
	ch[u][kind]=fa;
	pre[fa]=u;
	up(fa);
}

void splay(int u,int goal)
{
	int fa,kind;
	down(u);
	while(pre[u]!=goal)
	{
		if(pre[pre[u]]==goal)
        {
            down(pre[u]);
            down(u);
            rotate(u,L(pre[u])==u);
        }
		else
		{
			fa=pre[u];
			down(pre[fa]);
			down(fa);
			down(u);
			kind=L(pre[fa])==fa;
			if(ch[fa][kind]==u)
			{
				rotate(u,!kind);
				rotate(u,kind);
			}
			else
			{
				rotate(fa,kind);
				rotate(u,kind);
			}
		}
	}
	up(u);
	if(goal==0) root=u;
}

int getkth(int u,int k)
{
	down(u);
	int s=size[L(u)]+1;
	if(s==k) return u;
	if(s>k) return getkth(L(u),k);
	else return getkth(R(u),k-s);
}

void build(int &u,int l,int r,int fa)
{
	if(l>r) return ;
	int mid=(l+r)>>1;
	newnode(u,fa,a[mid]);
	build(L(u),l,mid-1,u);
	build(R(u),mid+1,r,u);
	up(u);
}

void init()
{
	root=tot=0;
	L(root)=R(root)=pre[root]=size[root]=val[root]=rev[root]=0;
	newnode(root,0,-1);
	newnode(R(root),root,-1);
	build(keytree,1,n,R(root));
	up(R(root));
	up(root);
}

int getpre(int u)
{
    down(u);
    u=L(u);
    down(u);
    while(R(u))
    {
        u=R(u);
        down(u);
    }
    return u;
}

void remove()
{
    if(L(root))
    {
        int i=getpre(root);
        splay(i,root);
        R(i)=R(root);
        pre[R(root)]=i;
        root=L(root);
        pre[root]=0;
        up(root);
    }
    else
    {
        root=R(root);
        pre[root]=0;
    }
}

int output=0;
void inorder(int u)
{
    down(u);
    if(L(u)) inorder(L(u));
    if(u!=1&&u!=2)
    {
        if(output) putchar(' ');
        else output=1;
        printf("%d",val[u]);
    }
    if(R(u)) inorder(R(u));
}

int main()
{
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
	int i,left,right;
	char op[20];
	scanf("%d",&t);
	while(t--)
	{
	    scanf("%d",&n);
		for(i=1;i<=n;i++) scanf("%d",&a[i]);
		scanf("%d%d",&left,&right);
		init();
		scanf("%d",&m);
		while(m--)
		{
			scanf("%s",op);
			if(strcmp(op,"MoveLeft")==0)
			{
			    scanf("%s",op);
			    if(op[0]=='L') left--;
			    else right--;
			}
			else if(strcmp(op,"MoveRight")==0)
			{
			    scanf("%s",op);
			    if(op[0]=='L') left++;
			    else right++;
			}
			else if(strcmp(op,"Insert")==0)
            {
                scanf("%s%d",op,&i);
                if(op[0]=='L')
                {
                    splay(getkth(root,left),0);
                    splay(getkth(root,left+1),root);
                }
			    else
                {
                    splay(getkth(root,right+1),0);
                    splay(getkth(root,right+2),root);
                }
                newnode(keytree,R(root),i);
                right++;
            }
            else if(strcmp(op,"Delete")==0)
            {
                scanf("%s",op);
                if(op[0]=='L') splay(getkth(root,left+1),0);
			    else splay(getkth(root,right+1),0);
			    remove();
			    right--;
            }
            else if(strcmp(op,"Reverse")==0)
            {
                splay(getkth(root,left),0);
                splay(getkth(root,right+2),root);
                rev[keytree]^=1;
            }
		}
		output=0;
		inorder(root);
		puts("");
	}
	return 0;
}


HDU 4286 Data Handler

标签:hdu   数据结构   

原文地址:http://blog.csdn.net/houserabbit/article/details/37996187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!