POJ 3481 Double Queue Treap

本文介绍了一种基于Treap的数据结构实现方法,包括插入、删除和查找操作的具体步骤及代码实现。通过递归方式实现对最大值和最小值节点的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接: http://poj.org/problem?id=3481
对于每个节点有val和key
操作3种:
1.加入节点val和key
2.查找key最大的节点,输出val,并删除节点
3.查找key最小的节点,输出val,并删除节点

Treap模板题
按key值构造Treap,最大点递归查找左孩子,最小点递归查找右孩子

代码:

#include <algorithm>
#include <cstdio>
#include <iostream>
#define sf scanf
#define pf printf
using namespace std;
const int maxn = 1000000 + 500,INF = 0x3f3f3f3f;
int ch[maxn][2],key[maxn],fix[maxn],fa[maxn],tot;
int val[maxn];
int root,sroot;
void Treap_Init(){
    root = sroot = 0;
    ch[sroot][0] = ch[sroot][1] = 0;
    fa[sroot] = sroot;
    key[sroot] = fix[sroot] = INF;
    tot = 1;
}
int NewNode(int FA,int k,int v){
    fa[tot] = FA;
    ch[tot][0] = ch[tot][1] = 0;
    key[tot] = k;
    val[tot] = v;
    fix[tot] = rand();
    return tot++;
}
void rotate(int rt,int kind){
    int prt = fa[rt];
    ch[prt][kind] = ch[rt][!kind];
    fa[ch[rt][!kind]] = prt;

    ch[fa[prt]][ ch[fa[prt]][1] == prt ] = rt;
    fa[rt] = fa[prt];

    ch[rt][!kind] = prt;
    fa[prt] = rt;
}
void Insert(int k,int v){
    int rt = root;
    while(ch[rt][k > key[rt]]) rt = ch[rt][k > key[rt]];
    ch[rt][k > key[rt]] = NewNode(rt,k,v);
    rt = ch[rt][k > key[rt]];
    while(fa[rt] != sroot && fix[rt] > fix[ fa[rt] ]){
        rotate(rt,ch[fa[rt]][1] == rt);
    }
    if(fa[rt] == sroot) root = rt;
}

void Delete(int rt){
    if(ch[rt][0] && ch[rt][1]){
        int nrt = ch[rt][0];
        if(fix[nrt] < fix[ch[rt][1]]) nrt = ch[rt][1];
        rotate(nrt,ch[rt][1] == nrt);
        Delete(rt);
    }
    else{
        int nrt;
        if(ch[rt][0] != sroot) nrt = ch[rt][0];
        else nrt = ch[rt][1];
        ch[fa[rt]][ch[fa[rt]][1] == rt] = nrt;
        fa[nrt] = fa[rt];
        if(fa[nrt] == sroot) root = nrt;
    }
}

int Find_Min(){
    int rt = root;
    while(ch[rt][0] != sroot) rt = ch[rt][0];
    return rt;
}
int Find_Max(){
    int rt = root;
    while(ch[rt][1] != sroot) rt = ch[rt][1];
    return rt;
}
int main(){
    int a,b,c;
    Treap_Init();
    while(~sf("%d",&a)){
        if(a == 0) break;
        else if(a == 1){
            sf("%d %d",&b,&c);
            Insert(c,b);
        }
        else if(a == 2){
            b = Find_Max();
            if(b == sroot) pf("0\n");
            else{
                pf("%d\n",val[b]);
                Delete(b);
            }
        }
        else{
            b = Find_Min();
            if(b == sroot) pf("0\n");
            else{
                pf("%d\n",val[b]);
                Delete(b);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值