bzoj3224(平衡树板子)

裸的平衡树
写的是treap

#include<bits/stdc++.h>
using namespace std; 
int n , root , tot;
const int INF = 0x7fffffff;
struct tree{
    int val , dat;
    int cnt , size;
    int l , r; 
}a[101000];
int read()
{
    int sum = 0;char c = getchar();bool flag = true;
    while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
    while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
    if(flag)  return sum;
     else return -sum;
}  
int New(int v)
{
    a[++tot].val = v;
    a[tot].dat = rand();
    a[tot].cnt = a[tot].size = 1;
    return tot;
}
void update(int x)
{
    a[x].size = a[a[x].l].size + a[a[x].r].size + a[x].cnt;
    return;
}
void build()
{
    New(-INF);New(INF);
    a[1].r = 2;root = 1;
    update(root);
    return;
}
void zig(int &p)//右旋 
{
    int q = a[p].l;
    a[p].l = a[q].r;a[q].r = p;p = q;
    update(a[p].r);update(p);
    return;
}
void zag(int &p)//左旋 
{
    int q = a[p].r;
    a[p].r = a[q].l;a[q].l = p;p = q;
    update(a[p].l);update(p);
    return;
} 
void insert(int &x,int v)
{
    if(x == 0)
    {
        x = New(v);
        return;
    }
    if(v == a[x].val)
    {
        a[x].cnt++;
        a[x].size++;
        return;
    }
    else 
    if(v > a[x].val)
    {
        insert(a[x].r , v);
        if(a[a[x].r].dat > a[x].dat) zag(x);//左旋 
    } 
    else 
    if(v < a[x].val)
    {
        insert(a[x].l , v);
        if(a[a[x].l].dat > a[x].dat) zig(x);//右旋 
    }
    update(x);
    return;
}
void dele(int &x,int v)
{
    if(x == 0) return;
    if(v == a[x].val)
    {
        if(a[x].cnt > 1)
        {
            a[x].cnt--;a[x].size--;
            return;
        }
        if(a[x].l || a[x].r)
        {
            if(a[x].r == 0|| a[a[x].l].dat > a[a[x].r].dat)
                zig(x) , dele(a[x].r , v);
            else
                zag(x) , dele(a[x].l , v);
            update(x);
        }
        else x = 0;
        return;
    }
    v < a[x].val ? dele(a[x].l , v) : dele(a[x].r , v);
    update(x);
    return;
}
int find_rank(int x,int v)
{
    if(v == a[x].val) return a[a[x].l].size + 1;
    return  v < a[x].val ? find_rank(a[x].l , v)
    : find_rank(a[x].r , v) + a[a[x].l].size + a[x].cnt; 
}
int find_num(int x,int rank)
{
    if(a[a[x].l].size >= rank) return find_num(a[x].l , rank);
    if(a[a[x].l].size + a[x].cnt >= rank) return a[x].val;
    return find_num(a[x].r , rank - a[a[x].l].size - a[x].cnt); 
}
int find_pre( int x , int v )
{
    int ans = 1;
    while(x)
    {
        if(a[x].val == v)
        {
            if(a[x].l > 0)
            {
                x = a[x].l;
                while(a[x].r > 0) x = a[x].r;
                ans = x;
            }
            break;
        }
        if(a[x].val < v && a[x].val > a[ans].val) ans = x;
        x = v < a[x].val ? a[x].l : a[x].r;
    }
    return a[ans].val;
}
int find_next( int x , int v )
{
    int ans = 2;
    while(x)
    {
        if(v == a[x].val)
        {
            if(a[x].r > 0)
            {
                x = a[x].r;
                while(a[x].l > 0) x = a[x].l;
                ans = x;
            }
            break;
        }
        if(a[x].val > v && a[x].val < a[ans].val) ans = x;
        x = v < a[x].val ? a[x].l : a[x].r; 
    }
    return a[ans].val;
}
int main()
{
    build();
    n = read();
    for(int i = 1;i <= n;++i)
    {
        int k = read() , x = read();
        if(k == 1) insert(root , x);
        if(k == 2) dele(root , x);
        if(k == 3) printf("%d\n",find_rank(root , x) - 1);
        if(k == 4) printf("%d\n",find_num(root , x + 1));
        if(k == 5) printf("%d\n",find_pre(root , x));
        if(k == 6) printf("%d\n",find_next(root , x));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a1035719430/article/details/81137161