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

【BZOJ1861】【Zjoi2006】Book 书架 Splay

时间:2015-04-21 11:22:06      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:bzoj1861   zjoi2006   book   书架   splay   

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/45166317");
}

题解:

随便来一种数据结构就好啦。
这里写的是平衡树(一眼直接想到,而且发现很水)

注意。。

呃或许也不用太注意。
就是那个Insert操作要你干什么千万要看明白……

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
#define ls son[x][0]
#define rs son[x][1]
#define is(x) (x==son[fa[x]][1])
#define inf 0x3f3f3f3f
using namespace std;
int src[N],n,m;
struct SPT
{
    int son[N][2],fa[N],root;
    int size[N],num[N];

    void pushup(int x)
    {
        size[x]=size[ls]+size[rs]+num[x];
    }
    void link(int x,int y,int d){son[y][d]=x,fa[x]=y;}
    void rotate(int x)
    {
        int y=fa[x],z=fa[y],i=is(x),t=son[x][!i];
        link(t,y,i),link(x,z,is(y)),link(y,x,!i);
        fa[0]=0,son[0][0]=son[0][1]=0;
        pushup(y);
    }
    void splay(int x,int d=0)
    {
        int y,z;
        while(fa[x]!=d)
        {
            y=fa[x],z=fa[y];
            if(z==d)rotate(x);
            else rotate(is(x)==is(y)?y:x),rotate(x);
        }
        pushup(x);
        if(!d)root=x;
    }
    int pred(int x)
    {
        splay(x);
        for(x=ls;rs;x=rs);
        return x;
    }
    int succ(int x)
    {
        splay(x);
        for(x=rs;ls;x=ls);
        return x;
    }
    int build(int L,int R)
    {
        int mid=L+R>>1,l=0,r=0;
        if(L<mid)l=build(L,mid-1);
        if(mid<R)r=build(mid+1,R);
        mid=src[mid],num[mid]=1;
        link(l,mid,0),link(r,mid,1);
        pushup(mid);
        return mid;
    }
    void init()
    {
        root=build(1,n);
        link(n+1,src[1],0),link(n+2,src[n],1);
    }
    void insert(int d,int x)
    {
        int suc=succ(d);
        splay(suc,d);
        link(x,suc,0);
        splay(x);
    }
    void remove(int x)
    {
        int pre=pred(x),suc=succ(x);
        splay(pre),splay(x,pre);
        link(rs,pre,1);
        splay(rs);
        ls=rs=0;
    }
    void Top(int x)
    {
        remove(x);
        insert(n+1,x);
    }
    void Bottom(int x)
    {
        remove(x);
        insert(pred(n+2),x);
    }
    void Insert(int x)
    {
        int t;scanf("%d",&t);
        if(t==0)return ;
        int pre=pred(x),suc=succ(x);
        remove(x);
        if(t==-1)insert(pred(pre),x);
        else insert(suc,x);
    }
    int Ask(int x)
    {
        splay(x);
        return size[ls];
    }
    int Query(int k)
    {
        int x=root;
        while(size[ls]+1!=k)
        {
            if(size[ls]>=k)x=ls;
            else k-=(size[ls]+1),x=rs;
        }
        return x;
    }
}spt;
char s[10];
int a,b;
int main()
{
    freopen("test.in","r",stdin);

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&src[i]);
    spt.init();
    while(m--)
    {
        scanf("%s%d",s,&a);
        if(s[0]==‘T‘)spt.Top(a);
        else if(s[0]==‘B‘)spt.Bottom(a);
        else if(s[0]==‘I‘)spt.Insert(a);
        else if(s[0]==‘A‘)printf("%d\n",spt.Ask(a));
        else printf("%d\n",spt.Query(a));
    }
    return 0;
}

【BZOJ1861】【Zjoi2006】Book 书架 Splay

标签:bzoj1861   zjoi2006   book   书架   splay   

原文地址:http://blog.csdn.net/vmurder/article/details/45166317

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