bzoj 3224: Tyvj 1728 普通平衡树

1 篇文章 0 订阅
1 篇文章 0 订阅

模板模板!!

#include <cstdio>
using namespace std;
const int maxn=1000010;
int n,opt,x;
int fa[maxn],son[maxn][2],key[maxn],cnt[maxn],size[maxn];
int siz,root;
inline void clear(int now)
{
	son[now][1]=son[now][0]=fa[now]=cnt[now]=key[now]=size[now];
}
inline int get(int now)
{
	return son[fa[now]][1]==now;
}
inline void update(int now)
{
	if (!now) return ;
	size[now]=cnt[now];
	if (son[now][0]) size[now]+=size[son[now][0]];
	if (son[now][1]) size[now]+=size[son[now][1]];
}
inline void rotate(int now)
{
	int old=fa[now],older=fa[old],which=get(now);
	son[old][which]=son[now][which^1];
	fa[son[old][which]]=old;
	fa[old]=now;son[now][which^1]=old;
	fa[now]=older;
	if (older) son[older][son[older][1]==old]=now;
	update(old);update(older);
}
inline void splay(int now)
{
	for (int f;f=fa[now];rotate(now))
	if (fa[f])
	if (get(now)==get(f)) rotate(f);
	else rotate(now);
	root=now;
}

inline void insert(int v)
{
	if (!root)
	{
		siz++;
		son[siz][0]=son[siz][1]=fa[siz]=0;
		key[siz]=v;
		size[siz]=1;
		cnt[siz]=1;
		root=siz;
		return ;
	}
	int now=root,f=0;
	while (1)
	{
		if (key[now]==v)
		{
			cnt[now]++;
			update(now);update(f);
			splay(now);
			break;
		}
		f=now;now=son[now][key[now]<v];
        if (now==0)
        {
            siz++;son[siz][0]=son[siz][1]=0;key[siz]=v;size[siz]=1;
            cnt[siz]=1;fa[siz]=f;son[f][key[f]<v]=siz;
            update(f);
			splay(siz);break;
        }		
	}
}
int find(int v)
{
    int ans=0,now=root;
    while (true)
    {
        if (v<key[now]) now=son[now][0]; else
        {
            if (son[now][0]) ans+=size[son[now][0]];
            if (v==key[now]) {splay(now); return ans+1;}
            ans+=cnt[now]; now=son[now][1];
        }
    }
}
int findkth(int x)
{
    int now=root;
    while (true)
    {
        if (son[now][0] && x<=size[son[now][0]]) now=son[now][0]; else
        {
           	int temp;
        	if (son[now][0]) temp=size[son[now][0]]+cnt[now];
            else temp=cnt[now];
            if (x<=temp) return key[now];
            x-=temp; now=son[now][1];
        }
    }
}
int prev()
    {
        int now=son[root][0];
        while (son[now][1]) now=son[now][1];
        return now;
    }
int succ()
    {
        int now=son[root][1];
        while (son[now][0]) now=son[now][0];
        return now;
    }
bool remove(int now)
{
    if (find(now)==-1) return false;
    if (cnt[root]>1) {cnt[root]--; return true;};
    if (!son[root][0] && !son[root][1]) {clear(root); root=0; return true;}
    if (!son[root][0])
    {
        int oldroot=root; root=son[root][1]; fa[root]=0; clear(oldroot); return true;
    }
    else if (!son[root][1])
    {
        int oldroot=root; root=son[root][0]; fa[root]=0; clear(oldroot); return true;
    }
    int leftbig=prev(),oldroot=root;
    splay(leftbig);
    fa[son[oldroot][1]]=root; son[root][1]=son[oldroot][1];
    clear(oldroot); update(root);
	return true;
}
int main()
{
	register int i,j;
	scanf("%d",&n);
	for (i=1;i<=n;i++)
	{
		scanf("%d %d",&opt,&x);
		switch(opt)
		{
			case 1:insert(x);break;
			case 2:remove(x);break;
			case 3:printf("%d\n",find(x));break;
			case 4:printf("%d\n",findkth(x));break;
			case 5:insert(x);printf("%d\n",key[prev()]);remove(x);break;
			case 6:insert(x);printf("%d\n",key[succ()]);remove(x);break;
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值