P3369 【模板】普通平衡树
#include
#include
#include
//======================================
const int maxn = 1e5+5;
const double alpha = 0.75;
struct Node
{
int l,r,val;
int size,fact;
bool exist;
}tzy[maxn];
int cnt,root;
void newnode(int &now,int val)
{
now=++cnt;
tzy[now].val=val;
tzy[now].size=tzy[now].fact=1;
tzy[now].exist=true;
}
bool imbalence(int now)
{
if(std::max(tzy[tzy[now].l].size,tzy[tzy[now].r].size)>tzy[now].size*alpha
||tzy[now].size-tzy[now].fact>tzy[now].size*0.3)
return true;
return false;
}
#include
std::vector<int> v;
void ldr(int now)
{
if(!now) return;
ldr(tzy[now].l);
if(tzy[now].exist)
v.push_back(now);
ldr(tzy[now].r);
}
void lift(int l,int r,int &now)
{
if(l==r)
{
now=v[l];
tzy[now].l=tzy[now].r=0;
tzy[now].size=tzy[now].fact=1;
return;
}
int m = (l+r)>>1;
while(l<m&&tzy[v[m]].val==tzy[v[m-1]].val)
m--;
now = v[m];
if(l<m) lift(l,m-1,tzy[now].l);
else tzy[now].l=0;
lift(m+1,r,tzy[now].r);
tzy[now].size=tzy[tzy[now].l].size+tzy[tzy[now].r].size+1;
tzy[now].fact=tzy[tzy[now].l].fact+tzy[tzy[now].r].fact+1;
}
void rebuild(int &now)
{
v.clear();
ldr(now);
if(v.empty())
{
now=0;
return;
}
lift(0,v.size()-1,now);
}
void update(int now,int end)
{
if(!now) return;
if(tzy[end].val<tzy[now].val)
update(tzy[now].l,end);
else update(tzy[now].r,end);
tzy[now].size=tzy[tzy[now].l].size+tzy[tzy[now].r].size+1;
}
void check(int &now,int end)
{
if(now==end) return;
if(imbalence(now))
{
rebuild(now);
update(root,now);
return;
}
if(tzy[end].val<tzy[now].val)
check(tzy[now].l,end);
else check(tzy[now].r,end);
}
void ins(int &now,int val)
{
if(!now)
{
newnode(now,val);
check(root,now);
return;
}
tzy[now].size++;
tzy[now].fact++;
if(val<tzy[now].val)
ins(tzy[now].l,val);
else ins(tzy[now].r,val);
}
void del(int now,int val)
{
if(tzy[now].exist&&tzy[now].val==val)
{
tzy[now].exist=false;
tzy[now].fact--;
check(root,now);
return;
}
tzy[now].fact--;
if(val<tzy[now].val)
del(tzy[now].l,val);
else del(tzy[now].r,val);
}
int getrank(int val)
{
int now=root,rank=1;
while(now)
{
if(val<=tzy[now].val)
now=tzy[now].l;
else
{
rank+=tzy[now].exist+tzy[tzy[now].l].fact;
now=tzy[now].r;
}
}
return rank;
}
int getnum(int rank)
{
int now=root;
while(now)
{
if(tzy[now].exist&&tzy[tzy[now].l].fact+tzy[now].exist==rank)
break;
else if(tzy[tzy[now].l].fact>=rank)
now=tzy[now].l;
else
{
rank-=tzy[tzy[now].l].fact+tzy[now].exist;
now=tzy[now].r;
}
}
return tzy[now].val;
}
int main()
{
// #ifndef ONLINE_JUDGE
// freopen("in.in", "r", stdin);
// freopen("out.out", "w", stdout);
// #endif
// clock_t c1 = clock();
//======================================
int t;
scanf("%d",&t);
while(t--)
{
int opt,x;
scanf("%d%d",&opt,&x);
switch(opt)
{
case 1:
ins(root,x);
break;
case 2:
del(root,x);
break;
case 3:
printf("%d\n",getrank(x));
break;
case 4:
printf("%d\n",getnum(x));
break;
case 5:
printf("%d\n",getnum(getrank(x)-1));
break;
case 6:
printf("%d\n",getnum(getrank(x+1)));
break;
}
}
//======================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}
#include
#include
#include
#include
using namespace std;
#define read(x) scanf("%d",&x)
#define MAXN 100005
const double alpha=0.75;//这个值随心就好了
struct node
{
int ls,rs;
int size,fact;
int val;
int exist;
node()
{
ls=rs=0;
size=fact=0;
val=0;
exist=0;
}
}tzy[MAXN];
int root=0;
int rt[MAXN],crt=0;
int cnt=0;
bool judge(int now)
{
return (tzy[now].exist&&
(alpha*(double)tzy[now].size<(double)max(tzy[tzy[now].ls].size,tzy[tzy[now].rs].size)
||(double)tzy[now].fact<alpha*(double)tzy[now].size));
}
void update(int now)
{
tzy[now].size=tzy[tzy[now].ls].size+tzy[tzy[now].rs].size+tzy[now].exist;
tzy[now].fact=tzy[tzy[now].ls].fact+tzy[tzy[now].rs].fact+tzy[now].exist;
return;
}
void ldr(int now)
{
if(!now)
return;
ldr(tzy[now].ls);
if(tzy[now].exist)
rt[++crt]=now;
ldr(tzy[now].rs);
return;
}
int rebuild(int l,int r)
{
if(l==r)
return 0;
int mid=(l+r)>>1;
tzy[rt[mid]].ls=rebuild(l,mid);
tzy[rt[mid]].rs=rebuild(mid+1,r);
update(rt[mid]);
return rt[mid];
}
void balance(int &now)
{
crt=0,ldr(now);
now=rebuild(1,crt+1);
}
void Insert(int &now,int val)
{
if(!now)
{
now=++cnt;
if(!root)
root=1;
tzy[now].val=val,tzy[now].ls=tzy[now].rs=0;
tzy[now].exist=tzy[now].size=tzy[now].fact=1;
}
else
{
if(tzy[now].val==val)
tzy[now].exist++;
else if(val<tzy[now].val)
Insert(tzy[now].ls,val);
else Insert(tzy[now].rs,val);
update(now);
if(judge(now))
balance(now);
}
}
void del(int &now,int val)
{
tzy[now].fact--;
if(tzy[now].val==val)
tzy[now].exist--;
else
{
if(tzy[now].val>val)
del(tzy[now].ls,val);
else del(tzy[now].rs,val);
}
update(now);
if(judge(now))
balance(now);
}
int rkdown(int now,int val)
{
if(!now) return 0;
if(tzy[now].exist&&tzy[now].val==val)
return tzy[tzy[now].ls].fact;
else if(val<tzy[now].val)
return rkdown(tzy[now].ls,val);
else return tzy[tzy[now].ls].fact+tzy[now].exist+rkdown(tzy[now].rs,val);
}
int getrank(int now,int val) // 查询 x 数的排名(排名定义为比当前数小的数的个数 +1 )
{
if(!now)
return 0;
if(tzy[now].exist&&tzy[now].val==val)
return tzy[tzy[now].ls].fact;
else if(val<tzy[now].val)
return getrank(tzy[now].ls,val);
else return tzy[tzy[now].ls].fact+tzy[now].exist+getrank(tzy[now].rs,val);
}
int getnum(int now,int k) // 查询排名为 x 的数
{
if(tzy[now].ls==tzy[now].rs)
return tzy[now].val;
if(k<=tzy[tzy[now].ls].fact)
return getnum(tzy[now].ls,k);
else if(k>tzy[tzy[now].ls].fact&&tzy[tzy[now].ls].fact+tzy[now].exist>=k)
return tzy[now].val;
else return getnum(tzy[now].rs,k-tzy[tzy[now].ls].fact-tzy[now].exist);
}
int main()
{
int n;
int t,x;
read(n);
while(n--)
{
read(t),read(x);
if(t==1)
Insert(root,x);
else if(t==2)
del(root,x);
else if(t==3)
printf("%d\n",getrank(root,x)+1); // 返回的排名加1是实际排名
else if(t==4)
printf("%d\n",getnum(root,x));
else if(t==5)
printf("%d\n",getnum(root,getrank(root,x)));
else printf("%d\n",getnum(root,getrank(root,x+1)+1));// else printf("%d\n",getnum(root,rkup(root,x)));
}
return 0;
}