fhqTreap

普通平衡树模板

// 用c++14 或 c++17提交
#include 
#include 
#include 
#include 
const int maxn = 1e5+5;
struct Node
{
    int l,r;
    int val,key;
    int size;
} fhq[maxn];
int cnt,root;
#include 
std::mt19937 rnd(233);
inline int newnode(int val)
{
    fhq[++cnt].val=val;  // 值,根据二叉搜索树的性质来构建树
    fhq[cnt].key=rnd();  // 随机数,根据二叉堆的性质来构建树
    fhq[cnt].size=1;   // 该节点及其子节点的总数
    return cnt;
}
inline void update(int now)
{
    fhq[now].size=fhq[fhq[now].l].size+fhq[fhq[now].r].size+1;
}
void split(int now,int val,int &x,int &y)// 分裂 <=val的值分给x,>val的值给y
{
    if(!now) x=y=0;
    else
    {
        if(fhq[now].val<=val)
        {
            x=now;
            split(fhq[now].r,val,fhq[now].r,y);
        }
        else
        {
            y=now;
            split(fhq[now].l,val,x,fhq[now].l);
        }
        update(now);
    }
}
int merge(int x,int y)  // 合并x和y
{
    if(!x||!y) return x+y;
    if(fhq[x].key>fhq[y].key)          
    {
        fhq[x].r=merge(fhq[x].r,y);
        update(x);
        return x;
    }
    else
    {
        fhq[y].l=merge(x,fhq[y].l);
        update(y);
        return y;
    }
}
int x,y,z;
inline void ins(int val)
{
    split(root,val,x,y);
    root=merge(merge(x,newnode(val)),y);
}
inline void del(int val)  // 删除一个值
{
    split(root,val,x,z);  // x = 小于等于val的部分,z = 大于val的部分
    split(x,val-1,x,y);   // x = 小于等于val-1的部分,y = 等于val的部分
    y=merge(fhq[y].l,fhq[y].r);  // 删除y的根节点
    root=merge(merge(x,y),z);   // 合并x,y,z
}
inline void getrank(int val)
{
    split(root,val-1,x,y);
    printf("%d\n",fhq[x].size+1);
    root=merge(x,y);
}
inline void getnum(int rank)
{
    int now=root;
    while(now)
    {
        if(fhq[fhq[now].l].size+1==rank)
            break;
        else if(fhq[fhq[now].l].size>=rank)
            now=fhq[now].l;
        else
        {
            rank-=fhq[fhq[now].l].size+1;
            now=fhq[now].r;
        }
    }
    printf("%d\n",fhq[now].val);
}
inline void pre(int val)
{
    split(root,val-1,x,y);
    int now = x;
    while(fhq[now].r)
        now = fhq[now].r;
    printf("%d\n",fhq[now].val);
    root=merge(x,y);
}
inline void nxt(int val)
{
    split(root,val,x,y);
    int now = y;
    while(fhq[now].l)
        now = fhq[now].l;
    printf("%d\n",fhq[now].val);
    root=merge(x,y);
}
int main(int argc, char const *argv[])
{
    /*
    #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(x);
            break;
        case 2:
            del(x);
            break;
        case 3:
            getrank(x);
            break;
        case 4:
            getnum(x);
            break;
        case 5:
            pre(x);
            break;
        case 6:
            nxt(x);
            break;
        }
    }

    //std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
    return 0;
}
/*
 * ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
 * │Esc│   │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│  ┌┐    ┌┐    ┌┐
 * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘  └┘    └┘    └┘
 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
 * │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │Num│ / │ * │ - │
 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
 * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │   │
 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
 * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  │               │ 4 │ 5 │ 6 │   │
 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
 * │ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│  Shift   │     │ ↑ │     │ 1 │ 2 │ 3 │   │
 * ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
 * │ Ctrl│ Win│ Alt│         Space         │ Alt│ Win│Menu│Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │←─┘│
 * └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
 */

文艺平衡树模板

#include 
#include 
#include 
const int maxn = 1e5+5;
struct Node
{
    int l,r;
    int val,key;
    int size;
    bool reverse;
}fhq[maxn];
int cnt,root;
#include 
std::mt19937 rnd(233);
inline int newnode(int val)
{
    fhq[++cnt].val=val;
    fhq[cnt].key=rnd();
    fhq[cnt].size=1;
    return cnt;
}
inline void update(int now)
{
    fhq[now].size=fhq[fhq[now].l].size+fhq[fhq[now].r].size+1;
}
inline void pushdown(int now)
{
    std::swap(fhq[now].l,fhq[now].r);
    fhq[fhq[now].l].reverse^=1;
    fhq[fhq[now].r].reverse^=1;
    fhq[now].reverse=false;
}
void split(int now,int siz,int &x,int &y)
{
    if(!now) x=y=0;
    else
    {
        if(fhq[now].reverse) pushdown(now);
        if(fhq[fhq[now].l].size<siz)
        {
            x=now;
            split(fhq[now].r,siz-fhq[fhq[now].l].size-1,fhq[now].r,y);
        }
        else
        {
            y=now;
            split(fhq[now].l,siz,x,fhq[now].l);
        }
        update(now);
    }
}
int merge(int x,int y)
{
    if(!x||!y) return x+y;
    if(fhq[x].key<fhq[y].key)
    {
        if(fhq[x].reverse) pushdown(x);
        fhq[x].r=merge(fhq[x].r,y);
        update(x);
        return x;
    }
    else
    {
        if(fhq[y].reverse) pushdown(y);
        fhq[y].l=merge(x,fhq[y].l);
        update(y);
        return y;
    }
}
void reverse(int l,int r)
{
    int x,y,z;
    split(root,l-1,x,y);
    split(y,r-l+1,y,z);
    fhq[y].reverse^=1;
    root=merge(merge(x,y),z);
}
void ldr(int now)
{
    if(!now) return;
    if(fhq[now].reverse)
        pushdown(now);
    ldr(fhq[now].l);
    printf("%d\n",fhq[now].val);
    ldr(fhq[now].r);
}
int main(int argc, char const *argv[])
{
    /*#ifndef ONLINE_JUDGE
        freopen("in.in", "r", stdin);
        freopen("out.out", "w", stdout);
    #endif
    clock_t c1 = clock();*/
    //======================================
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        root=merge(root,newnode(i));
    while(m--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        reverse(l,r);
    }
    ldr(root);
    //======================================

    //std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
    return 0;
}

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