splay
1操作:从平衡树中取出这个数,把rank改成最小,再insert进去
2操作:从平衡树中取出这个数,把rank改成最大,再insert进去
3操作:取出x和它相邻的数(1是右相邻,-1是左相邻,0直接continue)
4操作:查询x的rank
5操作:查询rank=x的数
/**************************************************************
Problem: 1861
User: syh0313
Language: C++
Result: Accepted
Time:2616 ms
Memory:22776 kb
****************************************************************/
#include
#include
#include
using
namespace
std;
const
int
maxn=500010;
int
n,m,root,topt,rk[maxn],ch[2][maxn],fa[maxn],cnt[maxn],si[maxn],key[maxn],up,down,rkto[4*maxn];
char
s[20];
void
updata(
int
x){si[x]=si[ch[0][x]]+si[ch[1][x]]+cnt[x];}
void
clear(
int
x) {rkto[rk[key[x]]]=0; rk[key[x]]=0; ch[0][x]=ch[1][x]=fa[x]=cnt[x]=si[x]=key[x]=0;}
int
get(
int
x) {
return
(x==ch[1][fa[x]]);}
void
ptf(
int
x)
{
if
(ch[0][x])
printf
(
"%d %d\n"
,x,ch[0][x]),ptf(ch[0][x]);
if
(ch[1][x])
printf
(
"%d %d\n"
,x,ch[1][x]),ptf(ch[1][x]);
}
void
rotate(
int
x)
{
int
old=fa[x],oldfa=fa[old];
int
wh=get(x);
ch[wh][old]=ch[wh^1][x]; fa[ch[wh^1][x]]=old;
ch[wh^1][x]=old; fa[old]=x; fa[x]=oldfa;
if
(oldfa) ch[ch[1][oldfa]==old][oldfa]=x;
updata(old); updata(x);
}
void
splay(
int
x)
{
for
(
int
ffa;(ffa=fa[x]);rotate(x))
if
(fa[ffa]) rotate((get(x)==get(ffa)?ffa:x));
root=x;
}
void
insert(
int
x)
{
if
(!root)
{
root=++topt; ch[0][topt]=ch[1][topt]=fa[topt]=0; cnt[topt]=si[topt]=1;
key[topt]=x;
return
;
}
int
now=root;
while
(1)
{
if
(key[now]==x) {cnt[now]++; updata(now); updata(fa[now]); splay(now);
return
;}
else
if
(rk[x]
{
if
(ch[0][now]) now=ch[0][now];
else
{
ch[0][now]=++topt; ch[0][topt]=ch[1][topt]=0; fa[topt]=now;
key[topt]=x; si[topt]=cnt[topt]=1; updata(fa[topt]); splay(topt);
return
;
}
}
else
{
if
(ch[1][now]) now=ch[1][now];
else
{
ch[1][now]=++topt; ch[0][topt]=ch[1][topt]=0; fa[topt]=now;
key[topt]=x; si[topt]=cnt[topt]=1; updata(fa[topt]); splay(topt);
return
;
}
}
}
}
void
del(
int
x)
{
int
now=root;
while
(1)
{
if
(key[now]==x)
break
;
if
(rk[x]<=rk[key[now]]) now=ch[0][now];
else
now=ch[1][now];
}
splay(now);
int
old=root,rs=ch[1][root];
if
(cnt[root]>1) {cnt[root]--; si[root]--;
return
;}
if
(!ch[0][root] && !ch[1][root]) {clear(root); root=0;
return
;}
if
(!ch[0][root]) {
int
k=ch[1][root]; clear(root); root=k; fa[root]=0;
return
;}
if
(!ch[1][root]) {
int
k=ch[0][root]; clear(root); root=k; fa[root]=0;
return
;}
now=ch[0][root];
while
(ch[1][now]) {now=ch[1][now];}
splay(now); ch[1][root]=rs; fa[rs]=root; clear(old); updata(root);
return
;
}
int
find2(
int
x)
{
int
now=root;
while
(1)
{
if
(key[now]==x)
break
;
if
(rk[key[now]]>=rk[x]) now=ch[0][now];
else
if
(rk[key[now]]
}
splay(now);
return
now;
}
int
findth(
int
x)
{
int
now=root;
while
(1)
{
if
(si[ch[0][now]]+cnt[now]>=x && si[ch[0][now]]
break
;
else
if
(si[ch[0][now]]>=x) now=ch[0][now];
else
if
(si[ch[0][now]]+cnt[now]
}
splay(now);
return
key[now];
}
int
find(
int
x)
{
int
now=root,ans=0;
while
(1)
{
if
(key[now]==x) {ans+=si[ch[0][now]];
break
;}
if
(rk[key[now]]>=rk[x]) now=ch[0][now];
else
if
(rk[key[now]]
}
splay(now);
return
ans;
}
int
read()
{
int
xx=0,ff=1;
char
c=
getchar
();
while
(c<
'0'
|| c>
'9'
) {
if
(c==
'-'
) ff=-1; c=
getchar
();}
while
(c>=
'0'
&& c<=
'9'
) {xx=(xx<<1)+(xx<<3)+c-
'0'
; c=
getchar
();}
return
xx*ff;
}
int
main()
{
n=read(); m=read(); up=down=100010;
for
(
register
int
i=1;i<=n;i++)
{
int
x; x=read();
rk[x]=++up; rkto[up]=x; insert(x);
}
for
(
register
int
i=1;i<=m;i++)
{
scanf
(
"%s"
,s+1);
if
(s[1]==
'Q'
) {
int
kk; kk=read();
printf
(
"%d\n"
,findth(kk));}
else
if
(s[1]==
'T'
)
{
int
xx; xx=read(); del(xx);
rk[xx]=--down; rkto[down]=xx; insert(xx);
}
else
if
(s[1]==
'B'
)
{
int
xx; xx=read(); del(xx);
rk[xx]=++up; rkto[up]=xx; insert(xx);
}
else
if
(s[1]==
'A'
) {
int
kk; kk=read();
printf
(
"%d\n"
,find(kk));}
else
if
(s[1]==
'I'
)
{
int
ss,tt; ss=read(); tt=read();
if
(!tt)
continue
;
int
rk1=find(ss)+1,rk2=rk1+tt;
int
p1=ss,p2=findth(rk2);
int
nn1=rk[p1],nn2=rk[p2];
del(p1); del(p2);
rk[p1]=nn2; rkto[nn2]=p1;
rk[p2]=nn1; rkto[nn1]=p2;
insert(p1); insert(p2);
}
}
return
0;
}