
#include<bits/stdc++.h>
#define MAXN 400005
using namespace std;
int n,q,a,b;
string tp;
int date[MAXN],bianhao[MAXN];
struct Splay{
int num[MAXN],ch[MAXN][2],sz[MAXN],f[MAXN],cnt[MAXN],rt,tot,tag[MAXN];
int get(int x){
return (x==ch[f[x]][1]);
}
int up(int x){
sz[x] = cnt[x];
if(ch[x][0])sz[x] = sz[x]+sz[ch[x][0]];
if(ch[x][1])sz[x] = sz[x]+sz[ch[x][1]];
return 0;
}
int rote(int x){
int y = f[x],z = f[y],k = get(x),p = get(y);
if(y==0)return 0;
if(z)ch[z][p] = x;
if(ch[x][k^1])f[ch[x][k^1]] = y;
ch[y][k] = ch[x][k^1];
ch[x][k^1] = y;
f[x] = z;
f[y] = x;
up(y);up(x);
return 0;
}
int splay(int x){
for(int y = f[x];(y = f[x]);rote(x)){
rote((get(x)==get(y))?y:x);
}
rt = x;
return 0;
}
int rank(int x){
int now=rt,ans=1;
while(1){
if(num[now]<=x){
ans = ans+sz[ch[now][0]];
if(num[now]==x){
splay(now);
return ans;
}
ans = ans+cnt[now];
now = ch[now][1];
}
else{
now = ch[now][0];
}
}
}
int pre(){//前继 比她小的最大
int now = ch[rt][0];
while(ch[now][1])now = ch[now][1];
return now;
}
int suc(){
int now = ch[rt][1];
while(ch[now][0])now = ch[now][0];
return now;
}
int add(int x){
int now = rt;
while(1){
if(num[now]==x){
cnt[now]++;
splay(now);
return 0;
}
int to = (num[now]<x);
if(!ch[now][to]){
tot++;
ch[now][to] = tot;
num[tot] = x;
f[tot] = now;
cnt[tot] = 1;
sz[tot] = 1;
splay(tot);
return 0;
}
else now = ch[now][to];
}
}
int kth(int x){
int now =rt;
while(1){
if(sz[ch[now][0]]<x&&ch[now][0]){
x = x-sz[ch[now][0]];
if(x<=cnt[now])return now;
x = x-cnt[now];
now = ch[now][1];
}
else if(!ch[now][0]){
if(x<=cnt[now])return now;
x = x-cnt[now];
now = ch[now][1];
}
else{
now = ch[now][0];
}
}
}
int del(int x){
splay(x);
int fu = pre(),ck = suc();
if(fu==0){
int hj = ch[rt][1];
ch[rt][0] = ch[rt][1] = f[rt] = 0;
rt = hj;
return 0;
}
if(ck==0){
int hj = ch[rt][0];
ch[rt][0] = ch[rt][1] = f[rt] = 0;
rt = hj;
return 0;
}
splay(fu);
splay2(ck);
ch[ch[ck][0]][0] = ch[ch[ck][0]][1] = f[ch[ck][0]] = 0;
ch[ck][0] = 0;
up(ch[ck][1]);
up(fu);
}
int chajinqu(int x,int y){
if(y==0)return 0;
splay(x);
int fu = pre(),ck = suc();
if(y==1&&ck!=0){
swap(bianhao[date[rt]],bianhao[date[ck]]);
swap(date[rt],date[ck]);
swap(num[rt],num[ck]);
}
else if(fu!=0){
swap(bianhao[date[rt]],bianhao[date[fu]]);
swap(date[rt],date[fu]);
swap(num[rt],num[fu]);
}
}
int splay2(int x){
for(int y = f[x];(y = f[x])!=rt;rote(x)){
if(f[y]!=rt)rote((get(x)==get(y))?y:x);
}
return 0;
}
int minl(){
int now = rt;
while(ch[now][0])now = ch[now][0];
return now;
}
int maxl(){
int now = rt;
while(ch[now][1])now = ch[now][1];
return now;
}
}T;
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>date[i];
bianhao[date[i]] = i;
T.add(i);
}
//知道了每个树节点所对于的书本编号....
for(int i=1;i<=q;i++){
cin>>tp;
if(tp=="Top"){
cin>>a;//把ma所对应的树的节点删掉,然后在树的最左插入...
T.del(bianhao[a]);
if(T.minl()==0){
T.ch[T.rt][0] = bianhao[a];
T.f[bianhao[a]] = T.rt;
T.up(bianhao[a]);T.up(T.rt);
}
else{
T.splay(T.minl());
T.ch[T.rt][0] = bianhao[a];
T.f[bianhao[a]] = T.rt;
T.up(bianhao[a]);T.up(T.rt);
}
}
else if(tp=="Bottom"){
cin>>a;//把ma所对应的树的节点删掉,然后在树的最右插入...
T.del(bianhao[a]);
if(T.maxl()==0){
T.ch[T.rt][1] = bianhao[a];
T.f[bianhao[a]] = T.rt;
T.up(bianhao[a]);T.up(T.rt);
}
else{
T.splay(T.maxl());
T.ch[T.rt][1] = bianhao[a];
T.f[bianhao[a]] = T.rt;
T.up(bianhao[a]);T.up(T.rt);
}
}
else if(tp=="Insert"){
//这里炸了
cin>>a>>b;
T.chajinqu(bianhao[a],b);
}
else if(tp=="Ask"){
cin>>a;
T.splay(bianhao[a]);
printf("%d\n",T.sz[T.ch[T.rt][0]]);
}
else if(tp=="Query"){
cin>>a;
printf("%d\n",date[T.kth(a)]);
}
}
}
有空来调,好毒....
来源:https://www.cnblogs.com/shatianming/p/12239460.html
