#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=100010;
struct node{
int v,s,fz,f,ch[2]; //ch[0]:left;ch[1]:right;
}a[maxn];
int root=1,t[maxn];
void push_up(int rt){
int l=a[rt].ch[0], r=a[rt].ch[1];
a[rt].s=a[l].s+a[r].s+1;
}
void push_down(int rt){
int l=a[rt].ch[0], r=a[rt].ch[1];
if(a[rt].fz){a[l].fz^=1; a[r].fz^=1; a[rt].fz=0;}
}
void out(int rt){
if(rt){out(a[rt].ch[0]); printf("%d(%d) ",a[rt].v,a[rt].s); out(a[rt].ch[1]);}
}
void rotate(int x,int op){
int y=a[x].f, z=a[y].f, B=a[x].ch[op];
a[x].ch[op]=y; a[y].f=x;
a[y].ch[!op]=B; a[B].f=y;
if(a[z].ch[0]==y)a[z].ch[0]=x;
else a[z].ch[1]=x;
a[x].f=z;
push_up(x); push_up(y);
}
void splay(int x,int to){
while(a[x].f!=to){
if(!a[a[x].f].f){
rotate(x,x==a[a[x].f].ch[0]);
}else{
int y=a[x].f, z=a[y].f;
int op=y==a[z].ch[0];
if(a[y].ch[op] != x){
rotate(y,op); rotate(x,op);
}else{
rotate(x,!op); rotate(x,op);
}
}
}
if(a[x].f==0)root=x;
}
void insert(int rt,int x){
int p=a[x].v>a[rt].v;
if(!a[rt].ch[p]){
a[rt].ch[p]=x; a[x].f=rt; splay(x,0);
}else insert(a[rt].ch[p],x);
push_up(rt);
}
int query(int rt,int x){
int l=a[rt].ch[0],r=a[rt].ch[1];
if(a[l].s>=x)return query(l,x);
else if(a[l].s+1==x)return rt;
else if(a[l].s+1<x)return query(r,x-a[l].s-1);
}
int find(int rt,int x){
if(rt==0)return 0;
int l=a[rt].ch[0],r=a[rt].ch[1];
if(a[rt].v==x)return rt;
else if(x<a[rt].v)return find(l,x);
else return find(r,x);
}
int query_prev(int rt){
int x=a[rt].ch[0];
if(x==0)return 0;
while(a[x].ch[1])x=a[x].ch[1];
splay(x,0);
return x;
}
int query_succ(int rt){
int x=a[rt].ch[1];
if(x==0)return 0;
while(a[x].ch[0])x=a[x].ch[0];
splay(x,0);
return x;
}
void del(int x){
int rt=find(root,x)
if(!rt)return;
splay(rt,0);
int l=a[rt].ch[0],r=a[rt].ch[1];
if(!l && !r){rt=0;return;}
if(!r){splay(l,0); a[l].ch[1]=0; push_up(l); return;}
if(!l){splay(r,0); a[l].ch[0]=0; push_up(r); return;}
splay(l,0); splay(r,l); a[r].ch[0]=0; push_up(r);push_up(l);
}
void del(int x,int y){
int s=query(root,x),t=query(root,y);
splay(s,0); splay(t,s); a[t].ch[0]=0;
push_up(t); push_up(s);
}
void reve(int x,int y){
int s=query(root,x),t=query(root,y);
splay(s,0); splay(t,s); a[a[t].ch[0]].fz=1;
}
int main(){
int n,m,x;
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&t[i]);
a[1].v=t[1]; a[1].s=1;
int j=2;
for(int i=1;i<=m;i++){
scanf("%d",&x);
for(;j<=x;j++){
a[j].v=t[j]; a[j].s=1;
insert(root,j);
}
int tmp=query(root,i);
printf("%d\n",a[tmp].v);
splay(tmp,0);
}
return 0;
}
SPLAY的各种操作
最新推荐文章于 2024-07-15 16:02:10 发布
这篇博客介绍了如何使用伸展树(Splay Tree)数据结构来高效地进行插入、查询和删除操作。文章通过C++代码展示了伸展树的基本操作,包括旋转、插入、查询、查找、删除以及反转等方法,并给出了一个实例来演示其在动态查询场景下的应用。
摘要由CSDN通过智能技术生成