這道題沒什麼好說的,
比較特殊的一點就是要維護父指針來查詢比指定點小的節點個數
具體看一下代碼就清楚了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 80010
using namespace std;
inline void read(int &x)
{
int s=0,w=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')w=-1;
c=getchar();
}
while(c<='9'&&c>='0')
{
s=(s<<3)+(s<<1)+c-'0';
c=getchar();
}
x=s*w;
}
inline void write(int x)
{
if(x<0)x=-x,putchar('-');
if(x>9)write(x/10);
putchar(x%10+'0');
}
template<class a,class b>class Pair
{
public:
a first;
b second;
Pair(){}
Pair(a x,b y){first=x,second=y;}
};
int seed=2333;
inline int Random(){return seed=seed*seed+seed+1;}
struct node
{
int val,key,size;
node *son[2],*fa;
node(int k);
inline void push_up();
}*nil=new node(0),*Root;
node::node(int k){val=k,key=Random(),size=1,son[0]=son[1]=fa=nil;}
inline void node::push_up()
{
size=son[0]->size+son[1]->size+1;
son[0]->fa=this;
son[1]->fa=this;
}
node* merge(node *a,node *b)
{
if(a==nil)return b;
if(b==nil)return a;
if(a->key<b->key)
{
a->son[1]=merge(a->son[1],b);
a->push_up();
return a;
}
else
{
b->son[0]=merge(a,b->son[0]);
b->push_up();
return b;
}
}
Pair<node*,node*>split(node *root,int k)
{
if(root==nil)return Pair<node*,node*>(nil,nil);
Pair<node*,node*>p;
if(root->son[0]->size>=k)
{
p=split(root->son[0],k);
root->son[0]=p.second;
root->push_up();
p.second=root;
return p;
}
else
{
p=split(root->son[1],k-root->son[0]->size-1);
root->son[1]=p.first;
root->push_up();
p.first=root;
return p;
}
}
int get_size(node *root)
{
int ans=root->son[0]->size+1;
while(root->fa!=nil)
{
if(root==root->fa->son[1])ans+=root->fa->son[0]->size+1;
root=root->fa;
}
return ans;
}
int n,m,a[MAXN],S,T;
node *pos[MAXN];
char opt[10];
int main()
{
nil->size=0,Root=nil;
Root->fa=nil;
read(n),read(m);
for(int i=1;i<=n;i++)
{
read(a[i]);
pos[a[i]]=new node(a[i]);
Root=merge(Root,pos[a[i]]);
}
while(m--)
{
scanf("%s",opt);
read(S);
if(opt[0]=='T')
{
Pair<node*,node*>a=split(Root,get_size(pos[S])-1),b=split(a.second,1);
Root=merge(b.first,merge(a.first,b.second));
}
else if(opt[0]=='B')
{
Pair<node*,node*>a=split(Root,get_size(pos[S])-1),b=split(a.second,1);
Root=merge(merge(a.first,b.second),b.first);
}
else if(opt[0]=='I')
{
read(T);
if(T)
{
int size=get_size(pos[S]);
Pair<node*,node*>a=split(Root,size-1),b=split(a.second,1);
if(T==1)
{
Pair<node*,node*>c=split(b.second,1);
Root=merge(merge(merge(a.first,c.first),b.first),c.second);
}
else
{
Pair<node*,node*>c=split(a.first,size-2);
Root=merge(merge(merge(c.first,b.first),c.second),b.second);
}
}
}
else if(opt[0]=='A')
write(get_size(pos[S])-1),putchar(10);
else
{
Pair<node*,node*>a=split(Root,S-1),b=split(a.second,1);
write(b.first->val),putchar(10);
Root=merge(a.first,merge(b.first,b.second));
}
}
luogu評測720ms
表現還可以,沒有比Splay慢太多