标签: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