替罪羊树

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;
}

你可能感兴趣的:(算法笔记)