bzoj 1861

Posted zhangleo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1861相关的知识,希望对你有一定的参考价值。

splay裸题嘛...

直接按书的编号顺序建splay,然后维护即可

把移动位置变成插入和删除

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
int ch[80005][2];
int f[80005];
int a[80005];
int siz[80005];
char s[15];
int rot,tot;
int n,m;
void update(int rt)

    siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1;

void rotate(int x)

    int y=f[x],z=f[y],k=(ch[y][1]==x);
    ch[z][ch[z][1]==y]=x,f[x]=z;
    ch[y][k]=ch[x][!k],f[ch[x][!k]]=y;
    ch[x][!k]=y,f[y]=x;
    update(y),update(x);

void splay(int x,int ed)

    while(f[x]!=ed)
    
        int y=f[x],z=f[y];
        if(z!=ed)
        
            if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
            else rotate(y);
        
        rotate(x);
    
    if(!ed)rot=x;

int buildtree(int l,int r,int fa)

    if(l==r)siz[a[l]]=1;f[a[l]]=a[fa];return a[l];
    int mid=(l+r)>>1;
    f[a[mid]]=a[fa];
    if(l<mid)ch[a[mid]][0]=buildtree(l,mid-1,mid);
    if(r>mid)ch[a[mid]][1]=buildtree(mid+1,r,mid);
    update(a[mid]);
    return a[mid];

int get_pre(int x)

    splay(x,0);
    int l=ch[x][0];
    while(ch[l][1])l=ch[l][1];
    return l;

int get_sub(int x)

    splay(x,0);
    int r=ch[x][1];
    while(ch[r][0])r=ch[r][0];
    return r;

void del(int l,int r)

    splay(l,0),splay(r,l);
    f[ch[r][0]]=0,ch[r][0]=0;

void ins(int l,int r,int v)

    splay(l,0),splay(r,l);
    ch[r][0]=v,f[v]=r,siz[v]=1;
    update(r),update(l);    

void push_top(int x)

    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int ffr=n+1,eed=get_sub(ffr);
    ins(ffr,eed,x);

void push_down(int x)

    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int eed=n+2,ffr=get_pre(eed);
    ins(ffr,eed,x);

void push_up(int x)

    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int ffr=get_pre(fr);
    ins(ffr,fr,x);

void push_back(int x)

    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int eed=get_sub(ed);
    ins(ed,eed,x);

void up_and_down(int x)

    int T;
    scanf("%d",&T);
    if(T==-1)push_up(x);
    else if(T==1)push_back(x);

void query_sum(int x)

    splay(x,0);
    printf("%d\n",siz[ch[x][0]]-1);

int query_num(int rt,int k)

    if(siz[ch[rt][0]]>=k)return query_num(ch[rt][0],k);
    else if(k>siz[ch[rt][0]]+1)return query_num(ch[rt][1],k-1-siz[ch[rt][0]]);
    else return rt;

void Query_num(int x)

    printf("%d\n",query_num(rot,x+1));

int main()

    scanf("%d%d",&n,&m);
    for(int i=2;i<=n+1;i++)scanf("%d",&a[i]);
    a[1]=n+1,a[n+2]=n+2;
    rot=buildtree(1,n+2,0);
    while(m--)
    
        int x,T;
        scanf("%s%d",s,&x);
        if(s[0]==T)push_top(x);
        else if(s[0]==B)push_down(x);
        else if(s[0]==I)up_and_down(x);
        else if(s[0]==A)query_sum(x);
        else Query_num(x);
    
    return 0;

 

以上是关于bzoj 1861的主要内容,如果未能解决你的问题,请参考以下文章

[题解]bzoj 1861 Book 书架 - Splay

bzoj1861 书架 splay版

BZOJ1861: [Zjoi2006]Book 书架

[BZOJ1861][Zjoi2006]Book 书架

bzoj1861 书架

BZOJ 1861: [Zjoi2006]Book 书架 (splay)