首页 > 其他分享 >FHQ-treap模板

FHQ-treap模板

时间:2024-11-25 17:44:13浏览次数:9  
标签:tmp ch cur int siz nullptr treap FHQ 模板

可以再加一个struct把整个树封装起来。。跟oiwiki学的

#include<bits/stdc++.h>
using namespace std;

#include<bits/stdc++.h>
using namespace std;

struct Node{
    Node *ch[2];
    int val, prio, cnt, siz;

    Node(int _val) : val(_val), cnt(1), siz(1){
        ch[0] = ch[1] = nullptr;
        prio = rand();
    }

    //   Node(Node *_node) {
    //     val = _node->val, prio = _node->prio, cnt = _node->cnt, siz = _node->siz;
    //   }

    void upd_siz(){
        siz = cnt;
        if (ch[0] != nullptr) siz += ch[0]->siz;
        if (ch[1] != nullptr) siz += ch[1]->siz;
    }
};

Node *rt;

pair<Node *, Node *> split(Node *cur, int key)
{
    if (cur == nullptr)
        return {nullptr, nullptr};
    if (cur->val <= key)
    {
        auto tmp = split(cur->ch[1], key);
        cur->ch[1] = tmp.first;
        cur->upd_siz();
        return {cur, tmp.second};
    }
    else
    {
        auto tmp = split(cur->ch[0], key);
        cur->ch[0] = tmp.second;
        cur->upd_siz();
        return {tmp.first, cur};
    }
}

tuple<Node *, Node *, Node *> split_by_rk(Node *cur, int rk)
{
    if (cur == nullptr)
        return {nullptr, nullptr, nullptr};
    int ls_siz = cur->ch[0] == nullptr ? 0 : cur->ch[0]->siz;
    if (rk <= ls_siz)
    {
        Node *l, *mid, *r;
        tie(l, mid, r) = split_by_rk(cur->ch[0], rk);
        cur->ch[0] = r;
        cur->upd_siz();
        return {l, mid, cur};
    }
    else if (rk <= ls_siz + cur->cnt)
    {
        Node *lt = cur->ch[0];
        Node *rt = cur->ch[1];
        cur->ch[0] = cur->ch[1] = nullptr;
        return {lt, cur, rt};
    }
    else
    {
        Node *l, *mid, *r;
        tie(l, mid, r) = split_by_rk(cur->ch[1], rk - ls_siz - cur->cnt);
        cur->ch[1] = l;
        cur->upd_siz();
        return {cur, mid, r};
    }
}

Node *merge(Node *u, Node *v)
{
    if (u == nullptr && v == nullptr)
        return nullptr;
    if (u != nullptr && v == nullptr)
        return u;
    if (v != nullptr && u == nullptr)
        return v;
    if (u->prio < v->prio)
    {
        u->ch[1] = merge(u->ch[1], v);
        u->upd_siz();
        return u;
    }
    else
    {
        v->ch[0] = merge(u, v->ch[0]);
        v->upd_siz();
        return v;
    }
}

void insert(int val)
{
    auto tmp = split(rt, val);
    auto l_tr = split(tmp.first, val - 1);
    Node *new_node;
    if (l_tr.second == nullptr)
    {
        new_node = new Node(val);
    }
    else
    {
        l_tr.second->cnt++;
        l_tr.second->upd_siz();
    }
    Node *l_tr_combined =
        merge(l_tr.first, l_tr.second == nullptr ? new_node : l_tr.second);
    rt = merge(l_tr_combined, tmp.second);
}

void del(int val)
{
    auto tmp = split(rt, val);
    auto l_tr = split(tmp.first, val - 1);
    if (l_tr.second->cnt > 1)
    {
        l_tr.second->cnt--;
        l_tr.second->upd_siz();
        l_tr.first = merge(l_tr.first, l_tr.second);
    }
    else
    {
        if (tmp.first == l_tr.second)
        {
            tmp.first = nullptr;
        }
        delete l_tr.second;
        l_tr.second = nullptr;
    }
    rt = merge(l_tr.first, tmp.second);
}

int qrk_by_val(Node *cur, int val)
{
    auto tmp = split(cur, val - 1);
    int ret = (tmp.first == nullptr ? 0 : tmp.first->siz) + 1;
    rt = merge(tmp.first, tmp.second);
    return ret;
}

int qval_by_rk(Node *cur, int rk)
{
    Node *l, *mid, *r;
    tie(l, mid, r) = split_by_rk(cur, rk);
    int ret = mid->val;
    rt = merge(merge(l, mid), r);
    return ret;
}

int qpre(int val)
{
    auto tmp = split(rt, val - 1);
    int ret = qval_by_rk(tmp.first, tmp.first->siz);
    rt = merge(tmp.first, tmp.second);
    return ret;
}

int qnxt(int val)
{
    auto tmp = split(rt, val);
    int ret = qval_by_rk(tmp.second, 1);
    rt = merge(tmp.first, tmp.second);
    return ret;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    srand(time(nullptr));
    int t;
    cin >> t;

    while (t--)
    {
        int mod, x;
        cin >> mod >> x;
        if (mod == 1)
            insert(x);
        if (mod == 2)
            del(x);
        if (mod == 3)
            cout << qrk_by_val(rt, x) << endl;
        if (mod == 4)
            cout << qval_by_rk(rt, x) << endl;
        if (mod == 5)
            cout << qpre(x) << endl;
        if (mod == 6)
            cout << qnxt(x) << endl;
    }
}

标签:tmp,ch,cur,int,siz,nullptr,treap,FHQ,模板
From: https://www.cnblogs.com/lyrrr/p/18568226

相关文章

  • 实验4 类的组合、继承、模板类、标准库
    实验任务2:代码:GradeCalc.hpp1#include<iostream>2#include<vector>3#include<string>4#include<algorithm>5#include<numeric>6#include<iomanip>78usingstd::vector;9usingstd::string;10......
  • 实验四 类的组合、继承、模板类、标准库
    1、实验任务二GradeCalc.hpp#include<iostream>#include<vector>#include<string>#include<algorithm>#include<numeric>#include<iomanip>usingstd::vector;usingstd::string;usingstd::cin;usingstd::cout;usingstd......
  • 实验4 类的组合、继承、模板类、标准库
    实验任务2GradeCalc.hpp源码#include<iostream>#include<vector>#include<string>#include<algorithm>#include<numeric>#include<iomanip>usingstd::vector;usingstd::string;usingstd::cin;usingstd::cout;usingstd:......
  • 实验4 类的组合、继承、模板类、标准库
    task1:1.点击查看代码#include<iostream>usingstd::cout;usingstd::endl;//类A的定义classA{public:A(intx0,inty0);voiddisplay()const;private:intx,y;};A::A(intx0,inty0):x{x0},y{y0}{}voidA::display()const{c......
  • 【模板】并查集
    题目描述如题,现在有一个并查集,你需要完成合并和查询操作。输入格式第一行包含两个整数N,M,表示共有N个元素和M个操作。接下来$M$行,每行包含三个整数Zi,Xi,Yi。当Zi=1时,将Xi与Yi所在的集合合并。当Zi=2时,输出Xi与Yi是否在同一集合内,是的输出Y;否则输出......
  • 实验四 类的组合、继承、模板类、标准库
     任务2:#include<iostream>#include<vector>#include<string>#include<algorithm>#include<numeric>#include<iomanip>usingstd::vector;usingstd::string;usingstd::cin;usingstd::cout;usingstd::endl;class......
  • 实验四 类的组合、继承、模板类、标准库
    任务1:task1.cpp1#include<iostream>23usingstd::cout;4usingstd::endl;56//类A的定义7classA{8public:9A(intx0,inty0);10voiddisplay()const;1112private:13intx,y;14};1516A::A(intx0,inty0):x{......
  • 实验4 类的组合、继承、模板类、标准库
    一、实验目的1.知道什么是类模板,会正确定义和使用简单的类模板2.会使用C++正确定义、使用派生类3.加深对类的组合机制(has-a)、类的继承机制(is-a)的领悟和理解4.练习标准库string,vector用法,能基于问题场景灵活使用5.针对具体问题场景,练习运用面向对象思维进行设计,组合使用......
  • Springboot如何利用模板,快速生成word文档?
    前言大家好,我是小徐啊。我们在使用SpringBoot开发的时候,有时候会遇到需要生成word文档的情况。一般情况下,就是将一些数据填充到word文档里面。其实Java是有开源的第三方jar包的。今天,小徐就来介绍下如何在SpringBoot里面生成word文档。如何设置首先,我们需要在pom.xml文件里面,引......
  • 实验四 类的组合、继承、模板、标准库
    2.Gradeclc.hpp`#includeincludeincludeincludeincludeincludeusingstd::vector;usingstd::string;usingstd::cin;usingstd::cout;usingstd::endl;classGradeCalc:publicvector{public:GradeCalc(conststring&cname,intsize);voidinpu......