照着指针版的打了个数组版的,
发现自己上了一节C++语法课。
重构什么的,最难在于找出深度最小的需要重构的节点,
毕竟多写一个函数不太优雅,
数组又不像指针那么方便直接修改。
如果你要传回一个变量的地址(因为你直接修改这个地址ch等等就直接跟着改了,十分方便)
函数不能写 int&
得写int *...............
删除还是不要重构,太浪费了。。。。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<vector>
#include<set>
#include<map>
using namespace std;
/*
namespace Scapegoat_Tree
{*/
#define maxn 500005
const double alp=0.8;
int val[maxn],lc[maxn],rc[maxn],siz[2][maxn],null=0; // 0 virtual included, 1 only alive
bool ext[maxn];
void upd(int now){ siz[0][now]=siz[0][lc[now]]+siz[0][rc[now]]+1,siz[1][now]=siz[1][lc[now]]+siz[1][rc[now]]+ext[now]; }
bool isBad(int now){ return ( siz[0][lc[now]]>=siz[0][now]*alp+5 ) || ( siz[0][rc[now]]>=siz[0][now]*alp+5); }
int root,tot;
int newNode(int v)
{
val[++tot]=v;
siz[0][tot]=siz[1][tot]=ext[tot]=1;
lc[tot]=rc[tot]=0;
return tot;
}
int seq[maxn],len;
void build(int &now,int L,int R)
{
if(L>R){ now=0;return;}
int mid=(L+R)>>1;
now=seq[mid];
build(lc[now],L,mid-1);
build(rc[now],mid+1,R);
upd(now);
}
void recycle(int now)
{
if(!now) return;
recycle(lc[now]);
if(ext[now]) seq[len++]=now;
recycle(rc[now]);
}
void rebuild(int &now)
{
len=0;
recycle(now);
build(now,0,len-1);
}
int* Insert(int& now,int v)
{
if(!now)
{
now=newNode(v);
return &null;
}
else
{
siz[0][now]++,siz[1][now]++;
int *res=Insert(v>=val[now]?rc[now]:lc[now],v);
if(isBad(now)) res=&now;
return res;
}
}
void Insert(int v)
{
int *tmp=Insert(root,v);
if(tmp) rebuild(*tmp);
}
void Delete(int now,int rk)
{
siz[1][now]--;
int tmp=siz[1][lc[now]]+ext[now];
if(tmp==rk && ext[now]) ext[now]=0;
else
{
if(rk<=tmp) Delete(lc[now],rk);
else Delete(rc[now],rk-tmp);
}
}
int Rank(int v)
{
int now=root,ret=1;
while(now)
{
if(val[now]>=v) now=lc[now];
else
{
ret+=siz[1][lc[now]]+ext[now];
now=rc[now];
}
}
return ret;
}
int Sank(int rk)
{
int now=root;
while(now)
{
if(siz[1][lc[now]]+ext[now]==rk && ext[now]) return val[now];
else if(siz[1][lc[now]]>=rk) now=lc[now];
else rk=rk-siz[1][lc[now]]-ext[now],now=rc[now];
}
}
void Erase(int v)
{
Delete(root,Rank(v));
//if(root && isBad(root)) rebuild(root);
}
/*
}
*/
inline void read(int &res)
{
static char ch;
static bool flag;
for(flag=0;!isdigit(ch=getchar());) if(ch=='-') flag=1;
for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0');
(flag) && (res=-res);
}
int main()
{
//freopen("1.out","w",stdout);
int n,tag,u;
read(n);
for(;n--;)
{
read(tag),read(u);
if(tag==1) Insert(u);
if(tag==2) Erase(u);
if(tag==3) printf("%d\n",Rank(u));
if(tag==4) printf("%d\n",Sank(u));
if(tag==5) printf("%d\n",Sank(Rank(u)-1));
if(tag==6) printf("%d\n",Sank(Rank(u+1)));
}
}