#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
const int N=120005,INF=0x3f3f3f3f;
struct Splay_Tree
{
struct Node
{
int val,Max,add,Size,son[2];
bool rev;
void init(int _val)
{
val=Max=_val,Size=1;
add=rev=son[0]=son[1]=0;
}
} T[N];
int fa[N],root,tot;
/*void pushDown(int x)///下放标记(序列操作)
{
if(x==0)return ;
if(T[x].add)
{
if(T[x].son[0])
{
T[T[x].son[0]].val+=T[x].add;
T[T[x].son[0]].Max+=T[x].add;
T[T[x].son[0]].add+=T[x].add;
}
if(T[x].son[1])
{
T[T[x].son[1]].val+=T[x].add;
T[T[x].son[1]].Max+=T[x].add;
T[T[x].son[1]].add+=T[x].add;
}
T[x].add=0;
}
if(T[x].rev)
{
if(T[x].son[0])T[T[x].son[0]].rev^=1;
if(T[x].son[1])T[T[x].son[1]].rev^=1;
swap(T[x].son[0],T[x].son[1]);
T[x].rev=0;
}
}*/
/*void pushUp(int x)///更新节点(序列操作)
{
T[x].Max=T[x].val,T[x].Size=1;
if(T[x].son[0])
{
T[x].Max=max(T[x].Max,T[T[x].son[0]].Max);
T[x].Size+=T[T[x].son[0]].Size;
}
if(T[x].son[1])
{
T[x].Max=max(T[x].Max,T[T[x].son[1]].Max);
T[x].Size+=T[T[x].son[1]].Size;
}
}*/
inline void up(int x)///更新节点(普通平衡树操作)
{
T[x].Size=1;
if(T[x].son[0])
T[x].Size+=T[T[x].son[0]].Size;
if(T[x].son[1])
T[x].Size+=T[T[x].son[1]].Size;
}
void Rotate(int x,int kind)///旋转,有左旋右旋(反正配合splay用就好了233)
{
int y=fa[x],z=fa[y];
T[y].son[!kind]=T[x].son[kind],fa[T[x].son[kind]]=y;
T[x].son[kind]=y,fa[y]=x;
T[z].son[T[z].son[1]==y]=x,fa[x]=z;
up(y);
}
void Splay(int x,int goal)///把下标为x的元素旋转到目标的儿子节点
{
if(x==goal)return ;
while(fa[x]!=goal)
{
int y=fa[x],z=fa[y];
//pushDown(z),pushDown(y),pushDown(x);
int rx=T[y].son[0]==x,ry=T[z].son[0]==y;
if(z==goal)Rotate(x,rx);
else
{
if(rx==ry)Rotate(y,ry);
else Rotate(x,rx);
Rotate(x,ry);
}
}
up(x);
if(goal==0)root=x;
}
int Select(int pos)///查找第k小元素
{
int u=root;
//pushDown(u);
while(T[T[u].son[0]].Size!=pos)
{
if(pos<T[T[u].son[0]].Size)u=T[u].son[0];
else
{
pos-=T[T[u].son[0]].Size+1;
u=T[u].son[1];
}
//pushDown(u);
}
Splay(u,root);
return u;
}
void update(int L,int R,int val)///序列操作的区间更新
{
int u=Select(L-1),v=Select(R+1);
Splay(u,0);
Splay(v,u);
T[T[v].son[0]].Max+=val;
T[T[v].son[0]].val+=val;
T[T[v].son[0]].add+=val;
}
void Reverse(int L,int R)///序列操作的区间翻转
{
int u=Select(L-1),v=Select(R+1);
Splay(u,0);
Splay(v,u);
T[T[v].son[0]].rev^=1;
}
int query(int L,int R)///区间操作的区间询问
{
int u=Select(L-1),v=Select(R+1);
Splay(u,0);
Splay(v,u);
return T[T[v].son[0]].Max;
}
int build(int L,int R)///区间操作建树
{
if(L>R)return 0;
if(L==R)return L;
int mid=(L+R)>>1,sL,sR;
T[mid].son[0]=sL=build(L,mid-1);
T[mid].son[1]=sR=build(mid+1,R);
fa[sL]=fa[sR]=mid;
up(mid);
return mid;
}
void init(int n)///区间操作,输入n个元素建树
{
T[0].init(-INF);
for(int i=1,x;i<=n;i++)
{
scanf("%d",&x);
T[i].init(x);
}
root=build(1,n),fa[root]=0;
fa[0]=0,T[0].son[1]=root,T[0].Size=0;
}
void Insert(int &t,int val,int par=0)///普通平衡树,往某个地方的下面插入元素,一般是插入根节点
{
if(t==0)
{
t=++tot;
T[t].init(val);
fa[t]=par;
Splay(tot,0);
}
else
{
int cur=t;
if(val<T[t].val)Insert(T[t].son[0],val,cur);
//else if(val==T[t].val)return ;
else Insert(T[t].son[1],val,cur);
up(cur);
}
}
int find(int t,int v)///普通平衡树查找值为v的元素
{
if(t==0)return 0;
else if(T[t].val==v)
{
Splay(t,0);
return t;
}
else if(v<T[t].val)return find(T[t].son[0],v);
else return find(T[t].son[1],v);
}
///删除根节点元素
void Delete()
{
if(!T[root].son[0])
{
fa[T[root].son[1]]=0;
root=T[root].son[1];
}
else
{
int cur=T[root].son[0];
while(T[cur].son[1])cur=T[cur].son[1];
Splay(cur,root);
T[cur].son[1]=T[root].son[1];
root=cur,fa[cur]=0,fa[T[root].son[1]]=root;
up(root);
}
}
int size()
{
return T[root].Size;
}
///从t开始找值为v的前驱,返回值
int pred(int t,int v)
{
if(t==0)return v;
else
{
if(v<=T[t].val)return pred(T[t].son[0],v);
else
{
int ans=pred(T[t].son[1],v);
if(ans==v)
ans=T[t].val,Splay(t,0);
return ans;
}
}
}
///查找下标t节点的前驱返回下标
int pred(int t)
{
Splay(t,0);
int u=T[t].son[0];
if(u==0)return fa[t];
while(T[u].son[1])u=T[u].son[1];
return u;
}
///从t开始找值为v的后继,返回值
int succ(int t,int v)
{
if(t==0)return v;
else
{
if(v>=T[t].val)return succ(T[t].son[1],v);
else
{
int ans=succ(T[t].son[0],v);
if(ans==v)
ans=T[t].val,Splay(t,0);
return ans;
}
}
}
///查找下标t节点的后继返回下标
int succ(int t)
{
Splay(t,0);
int u=T[t].son[1];
if(u==0)return fa[t];
while(T[u].son[0])u=T[u].son[0];
return u;
}
void Preorder( int t ){///输出成序列顺便检查是否有逻辑错误
if( !t ) return;
Preorder( T[t].son[0] );
if(T[t].son[0]&&fa[T[t].son[0]]!=t)
printf("!");
printf("%d " , T[t].val );
Preorder( T[t].son[1] );
}
void init()///普通平衡树初始化
{
T[1].init(-INF);
tot=root=1;
}
void update(int x)///更新下标为x的节点。。手动操作后调用
{
while(x!=0)
up(x),x=fa[x];
}
};