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

bzoj 1861

时间:2019-07-02 13:28:16      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:while   name   can   iostream   oid   lib   col   for   update   

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

标签:while   name   can   iostream   oid   lib   col   for   update   

原文地址:https://www.cnblogs.com/zhangleo/p/11120039.html

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