Binary Index Tree
struct BinaryIndexTree
{
const static int __=4e5+5;
ll a[__];int c[__],idx,siz;
BinaryIndexTree() {clear();}
void push_back(ll x){a[++idx]=x;}
int size() {return siz;}
void build()
{
sort(a+1,a+1+idx);
idx=unique(a+1,a+1+idx)-a-1;
}
int get(ll x)
{
return lower_bound(a+1,a+1+idx,x)-a;
}
void insert(ll x)
{
++siz;
for(int i=get(x);i<=idx;i+=i&-i)
++c[i];
}
void erase(ll x)
{
--siz;
for(int i=get(x);i<=idx;i+=i&-i)
--c[i];
}
int sum(int p)
{
int res=0;
for(int i=p;i;i-=i&-i)
res+=c[i];
return res;
}
//x数的排名
int rank(ll x)
{
int res=1;
for(int i=get(x)-1;i;i-=i&-i)
res+=c[i];
return res;
}
//第x个数
ll operator[](int x)
{
int p=idx;
for(int l=1,r=idx;l<=r;)
{
int mid=(l+r)>>1,s=0;
if(sum(mid)>=x)
p=mid,r=mid-1;
else l=mid+1;
}
return a[p];
}
//>x的最小数
ll greater(ll x)
{
int p=idx,l=get(x);
for(int y=sum(l++),r=idx;l<=r;)
{
int mid=(l+r)>>1;
if(sum(mid)>y)
p=mid,r=mid-1;
else l=mid+1;
}
return a[p];
}
//<x的最大数
ll less(ll x)
{
int p=1,r=get(x)-1;
for(int y=sum(r),l=1;l<=r;)
{
int mid=(l+r)>>1;
if(sum(mid-1)<y)
p=mid,l=mid+1;
else r=mid-1;
}
return a[p];
}
//>x的数的个数
int upper(ll x){return siz-sum(get(x));}
//<x的数的个数
int lower(ll x){return sum(get(x)-1);}
void clear() {idx=siz=0;mem(c,0);}
}bit;
AVL
struct AVL
{
#define fa(x) t[x].nex[0]
#define ls(x) t[x].nex[1]
#define rs(x) t[x].nex[2]
const static int __=1e5+5;
struct node
{
int val;
int nex[3],cont,siz,h;
void set(int pre,int v)
{
nex[0]=pre,val=v;
}
void clear()
{
cont=siz=h=1;
mem(nex,0);
}
}t[__];
int root;
void pushup(int x)
{
t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
t[x].h=max(t[ls(x)].h,t[rs(x)].h)+1;
}
struct memory
{
static const int __=1e5+5;
int idx,trash[__];
int get()
{
if(trash[0])return trash[trash[0]--];
return ++idx;
}
void del(int x){trash[++trash[0]]=x;}
void clear(){idx=trash[0]=0;}
}M;
AVL() {clear();}
void rotate(int x)
{
int f=fa(x),k=(x==ls(f))?1:2;
if(fa(f))
t[fa(f)].nex[f==ls(fa(f))?1:2]=x;
else root=x;
t[f].nex[k]=t[x].nex[3-k];
t[x].nex[3-k]=f;
fa(x)=fa(f),fa(f)=x;
if(t[f].nex[k])fa(t[f].nex[k])=f;
pushup(f),pushup(x);
}
void up(int x)
{
for(;x;x=fa(x))
{
pushup(x);
int dh=t[ls(x)].h-t[rs(x)].h;
if(dh<=-2)
{
x=rs(x);
if(t[ls(x)].h<=t[rs(x)].h)rotate(x);
else x=ls(x),rotate(x),rotate(x);
}
if(dh>=2)
{
x=ls(x);
if(t[ls(x)].h>=t[rs(x)].h)rotate(x);
else x=rs(x),rotate(x),rotate(x);
}
}
}
void insert(int v)
{
int x=root,y=0;
while(x && t[x].val!=v)
if(v<t[y=x].val)x=ls(x);
else x=rs(x);
if(x)++t[x].cont;
else
{
x=M.get();
t[x].clear();
t[x].set(y,v);
if(!y)root=x;
else if(v<t[y].val)ls(y)=x;
else rs(y)=x;
}
up(x);
}
void erase(int v)
{
int x=root;
while(x && t[x].val!=v)
if(v<t[x].val)x=ls(x);
else x=rs(x);
if(!x)return;
--t[x].cont;
if(!t[x].cont)
{
loop:
int k=(x==ls(fa(x)))?1:2;
if(!ls(x) || !rs(x))
{
int y=ls(x)?ls(x):rs(x);
if(x==root)root=y;
else t[fa(x)].nex[k]=y;
fa(y)=fa(x);
}
else
{
int y=x;
for(x=ls(x);rs(x);x=rs(x));
t[y].val=t[x].val;
t[y].cont=t[x].cont;
goto loop;
}
M.del(x),x=fa(x);
}
up(x);
}
void clear()
{
root=0;
M.clear();
}
}T;
Splay
struct Splay
{
#define fa(x) t[x].nex[0]
#define ls(x) t[x].nex[1]
#define rs(x) t[x].nex[2]
const static int __=1e5+5;
struct node
{
int val;
int nex[3],cont,siz;
void set(int pre,int v)
{
nex[0]=pre,val=v;
}
void clear()
{
cont=siz=1;
mem(nex,0);
}
}t[__];
int root;
void pushup(int x)
{
t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
}
struct memory
{
static const int __=1e5+5;
int idx,trash[__];
int get()
{
if(trash[0])return trash[trash[0]--];
return ++idx;
}
void del(int x){trash[++trash[0]]=x;}
void clear(){idx=trash[0]=0;}
}M;
Splay() {clear();}
void rotate(int x)
{
int f=fa(x),k=(x==ls(f))?1:2;
if(fa(f))
t[fa(f)].nex[f==ls(fa(f))?1:2]=x;
else root=x;
t[f].nex[k]=t[x].nex[3-k];
t[x].nex[3-k]=f;
fa(x)=fa(f),fa(f)=x;
if(t[f].nex[k])fa(t[f].nex[k])=f;
pushup(f),pushup(x);
}
void splay(int x,int y=0)
{
while(fa(x)!=y)
{
int f=fa(x),ff=fa(f);
if(ff==y)rotate(x);
else
if((x==ls(f))==(f==ls(ff)))
rotate(f),rotate(x);
else rotate(x),rotate(x);
}
}
void insert(int v)
{
int x=root,y=0;
while(x && t[x].val!=v)
if(v<t[y=x].val)x=ls(x);
else x=rs(x);
if(x)++t[x].cont;
else
{
x=M.get();
t[x].clear();
t[x].set(y,v);
if(!y)root=x;
else if(v<t[y].val)ls(y)=x;
else rs(y)=x;
}
splay(x);
}
void erase(int v)
{
int x=root,y=0;
while(x && t[x].val!=v)
if(v<t[y=x].val)x=ls(x);
else x=rs(x);
if(!x){splay(y);return;}
splay(x);
--t[x].cont;
if(!t[x].cont)
{
if(!ls(x) || !rs(x))
{
root=ls(x)?ls(x):rs(x);
fa(root)=0;
}
else
{
int y=rs(x);
root=ls(x),fa(ls(x))=0;
M.del(x);
for(x=root;rs(x);x=rs(x));
splay(x);
rs(x)=y,fa(y)=x;
pushup(x);
}
}
}
void clear()
{
root=0;
M.clear();
}
}T;
Treap
struct Treap
{
#define fa(x) t[x].nex[0]
#define ls(x) t[x].nex[1]
#define rs(x) t[x].nex[2]
const static int __=1e5+5;
struct node
{
int val,key;
int nex[3],cont,siz;
void set(int pre,int v)
{
nex[0]=pre,val=v;
}
void clear()
{
key=rand();
cont=siz=1;
mem(nex,0);
}
}t[__];
int root;
void pushup(int x)
{
t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
}
struct memory
{
static const int __=1e5+5;
int idx,trash[__];
int get()
{
if(trash[0])return trash[trash[0]--];
return ++idx;
}
void del(int x){trash[++trash[0]]=x;}
void clear(){idx=trash[0]=0;}
}M;
Treap() {srand(time(0));clear();}
void rotate(int x)
{
int f=fa(x),k=(x==ls(f))?1:2;
if(fa(f))
t[fa(f)].nex[f==ls(fa(f))?1:2]=x;
else root=x;
t[f].nex[k]=t[x].nex[3-k];
t[x].nex[3-k]=f;
fa(x)=fa(f),fa(f)=x;
if(t[f].nex[k])fa(t[f].nex[k])=f;
pushup(f),pushup(x);
}
void up(int x)
{
for(;x;x=fa(x))
{
pushup(x);
if(fa(x) && t[x].key<t[fa(x)].key)
rotate(x);
}
}
void insert(int v)
{
int x=root,y=0;
while(x && t[x].val!=v)
if(v<t[y=x].val)x=ls(x);
else x=rs(x);
if(x)++t[x].cont;
else
{
x=M.get();
t[x].clear();
t[x].set(y,v);
if(!y)root=x;
else if(v<t[y].val)ls(y)=x;
else rs(y)=x;
}
up(x);
}
void erase(int v)
{
int x=root;
while(x && t[x].val!=v)
if(v<t[x].val)x=ls(x);
else x=rs(x);
if(!x)return;
--t[x].cont;
if(!t[x].cont)
{
loop:
int k=(x==ls(fa(x)))?1:2;
if(!ls(x) || !rs(x))
{
int y=ls(x)?ls(x):rs(x);
if(x==root)root=y;
else t[fa(x)].nex[k]=y;
fa(y)=fa(x);
}
else
{
int y=x;
for(x=ls(x);rs(x);x=rs(x));
t[y].val=t[x].val;
t[y].cont=t[x].cont;
goto loop;
}
M.del(x),x=fa(x);
}
up(x);
}
void clear()
{
root=0;
M.clear();
}
}T;
Scapegoat Tree
struct ScapegoatTree
{
#define fa(x) t[x].nex[0]
#define ls(x) t[x].nex[1]
#define rs(x) t[x].nex[2]
const static int __=1e5+5;
constexpr static double alp=0.75;
struct node
{
int val;
int nex[3],cont,siz,num;
void set(int pre,int v,int c)
{
nex[0]=pre,val=v,cont=c;
}
void clear()
{
cont=siz=num=1;
mem(nex,0);
}
}t[__];
int root,c[__],cont[__];
void pushup(int x)
{
t[x].num=1+t[ls(x)].num+t[rs(x)].num;
t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
}
struct memory
{
static const int __=1e5+5;
int idx,trash[__];
int get()
{
if(trash[0])return trash[trash[0]--];
return ++idx;
}
void del(int x){trash[++trash[0]]=x;}
void clear(){idx=trash[0]=0;}
}M;
ScapegoatTree() {clear();}
void dfs(int x)
{
if(ls(x))dfs(ls(x));
c[++c[0]]=t[x].val;
cont[c[0]]=t[x].cont;
M.del(x);
if(rs(x))dfs(rs(x));
}
int build(int f,int l,int r)
{
if(l>r)return 0;
int x=M.get(),m=(l+r)>>1;
t[x].clear();
t[x].set(f,c[m],cont[m]);
ls(x)=build(x,l,m-1);
rs(x)=build(x,m+1,r);
pushup(x);
return x;
}
void rebuild(int x)
{
//pf("rebuild %d\n",t[x].val);
int f=fa(x);
c[0]=0,dfs(x);
int y=build(f,1,c[0]);
if(!f)root=y;
else t[f].nex[(x==ls(f))?1:2]=y;
}
bool check(int x)
{
double k=t[x].num*alp;
if(t[ls(x)].num>k || t[rs(x)].num>k)
return true;
return false;
}
void up(int x)
{
int y=0;
for(;x;x=fa(x))
{
pushup(x);
if(check(x))y=x;
}
if(y)rebuild(y);
}
void insert(int v)
{
int x=root,y=0;
while(x && t[x].val!=v)
if(v<t[y=x].val)x=ls(x);
else x=rs(x);
if(x)++t[x].cont;
else
{
x=M.get();
t[x].clear();
t[x].set(y,v,1);
if(!y)root=x;
else if(v<t[y].val)ls(y)=x;
else rs(y)=x;
}
up(x);
}
void erase(int v)
{
int x=root;
while(x && t[x].val!=v)
if(v<t[x].val)x=ls(x);
else x=rs(x);
if(!x)return;
--t[x].cont;
if(!t[x].cont)
{
loop:
int k=(x==ls(fa(x)))?1:2;
if(!ls(x) || !rs(x))
{
int y=ls(x)?ls(x):rs(x);
if(x==root)root=y;
else t[fa(x)].nex[k]=y;
fa(y)=fa(x);
}
else
{
int y=x;
for(x=ls(x);rs(x);x=rs(x));
t[y].val=t[x].val;
t[y].cont=t[x].cont;
goto loop;
}
M.del(x),x=fa(x);
}
up(x);
}
void clear()
{
root=0;
M.clear();
}
}T;
Treap(without rotate)
struct Treap
{
#define fa(x) t[x].nex[0]
#define ls(x) t[x].nex[1]
#define rs(x) t[x].nex[2]
const static int __=1e5+5;
struct node
{
int val,key;
int nex[3],cont,siz;
void clear()
{
key=rand();
cont=siz=1;
mem(nex,0);
}
}t[__];
int root;
void pushup(int x)
{
t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
}
struct memory
{
static const int __=1e5+5;
int idx,trash[__];
int get()
{
if(trash[0])return trash[trash[0]--];
return ++idx;
}
void del(int x){trash[++trash[0]]=x;}
void clear(){idx=trash[0]=0;}
}M;
Treap() {srand(time(0));clear();}
void up(int x)
{
for(;x;x=fa(x))pushup(x);
}
int find(int v)
{
int x=root;
while(x && t[x].val!=v)
if(v<t[x].val)x=ls(x);
else x=rs(x);
return x;
}
void insert(int v)
{
int x=find(v);
if(x){++t[x].cont;up(x);return;}
pii y=split(root,v);
t[x=M.get()].clear();
t[x].val=v;
root=merge(merge(y.fi,x),y.se);
}
void erase(int v)
{
int x=find(v);
if(!x)return;
if(--t[x].cont){up(x);return;}
pii y=split(root,v-1);
pii z=split(y.se,v);
root=merge(y.fi,z.se);
}
pii split(int x,int v)
{
int rt[3]={0},now[3]={0};
while(x)
{
int k=(t[x].val<=v)?1:2;
if(!rt[k])rt[k]=x;
else fa(t[now[k]].nex[3-k]=x)=now[k];
now[k]=x,x=t[x].nex[3-k];
}
rs(now[1])=0,up(now[1]);
ls(now[2])=0,up(now[2]);
return mp(rt[1],rt[2]);
}
int merge(int x,int y)
{
if(!x || !y)return x?x:y;
int rt[3]={0,x,y},z=0,d=0;
while(rt[1] && rt[2])
{
int k=(t[rt[1]].key<=t[rt[2]].key)?1:2;
if(!rt[1] || !rt[2])k=(rt[1]?1:2);
if(!rt[0])rt[0]=rt[k];
else fa(t[z].nex[d]=rt[k])=z;
z=rt[k],rt[k]=t[rt[k]].nex[d=3-k];
}
fa(t[z].nex[d]=rt[1]?rt[1]:rt[2])=z;
up(z);
return rt[0];
}
void clear()
{
root=0;
M.clear();
}
}T;