zoukankan      html  css  js  c++  java
  • BZOJ-3224 普通平衡树

    一道BST的练习题。

    Treap版:

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cctype>
    #include <cstring>
    #define rep(i, l, r) for(int i=l; i<=r; i++)
    #define clr(x, c) memset(x, c, sizeof(x))
    #define update(x) s[x]=s[l[x]]+s[r[x]]+1
    #define maxn 100009
    #define inf 0x7fffffff
    using namespace std;
    inline int read()
    {
    	int x=0, f=1; char ch=getchar();
    	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    	while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
    	return x*f;
    }
    int n=read();
    
    
    int l[maxn], r[maxn], s[maxn], k[maxn], pr[maxn], roof, V;
    inline void Init(){srand(233); roof=V=0;}
    inline void Left(int &v)
    {
    	int u=r[v];
    	r[v]=l[u], l[u]=v;
    	update(v), update(u);
    	v=u;
    }
    inline void Right(int &v)
    {
    	int u=l[v];
    	l[v]=r[u], r[u]=v;
    	update(v), update(u);
    	v=u;
    }
    void Insert(int x, int &v)
    {
    	if (!v)
    	{
    		v=++V; l[v]=r[v]=0, s[v]=1, k[v]=x, pr[v]=rand(); return;
    	}
    	if (x < k[v])
    	{
    		Insert(x, l[v]); update(v);
    		if (pr[l[v]] > pr[v]) Right(v);
    	}
    	else 
    	{
    		Insert(x, r[v]); update(v);
    		if (pr[r[v]] > pr[v]) Left(v);
    	}
    }
    void Delete(int x, int &v)
    {
    	if (x==k[v])
    	{
    		if (!l[v]) {v=r[v]; return;}
    		else if (!r[v]) {v=l[v]; return;}
    		else if (pr[l[v]] > pr[r[v]]) {Right(v); Delete(x, r[v]);}
    		else {Left(v); Delete(x, l[v]);}
    	} else Delete(x, x<k[v] ? l[v] : r[v]);
    	update(v);
    }
    int Rank(int x, int v)
    {
    	if (!v) return 0;
    	if (x>k[v]) return s[l[v]]+1+Rank(x, r[v]);
    	else return Rank(x, l[v]);
    }
    int Select(int n, int v)
    {
    	if (s[l[v]]==n) return k[v];
    	if (n>s[l[v]]) return Select(n-s[l[v]]-1, r[v]);
    	else return Select(n, l[v]);
    }
    int Suf(int x)
    {
    	int rec=inf;
    	for(int v=roof; v; v=x<k[v] ? l[v] : r[v]) 
    		if (k[v]>x) rec=min(rec, k[v]);
    	return rec;
    }
    int Pre(int x)
    {
    	int rec=-inf;
    	for(int v=roof; v; v=x<=k[v] ? l[v] : r[v]) 
    		if (k[v]<x) rec=max(rec, k[v]);
    	return rec;
    }
    
    int main()
    {
    	Init(); 
    	rep(i, 1, n)
    	{
    		int a=read();
    		if (a==1) Insert(read(), roof);
    		else if (a==2) Delete(read(), roof);
    		else if (a==3) printf("%d
    ", Rank(read(), roof)+1);
    		else if (a==4) printf("%d
    ", Select(read()-1, roof));
    		else if (a==5) printf("%d
    ", Pre(read())); else printf("%d
    ", Suf(read()));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    linux ramdisk
    linux系统灵活运用灯[android课程3]
    linux编译注解
    Linux内核3.0移植并基于Initramfs根文件系统启动
    linux0.11文件分析
    2.2linux内核移植简介
    sudo: ./sd_fusing.sh:找不到命令
    Tiny4412之C语言实现流水灯,Tiny4412裸机程序[3]
    Exynos 4412的启动过程分析[2]
    POJ 3009 Curling 2.0 {深度优先搜索}
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4445344.html
Copyright © 2011-2022 走看看