fhq-Treap 文艺平衡树代码记录

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<string>
using namespace std;
const int N=1e4+10;
int a[N];
int root;
int idx;
int x,y,z;
struct node{
    int l,r;
    int size;
    int val;
    int key;
    int lazy;
}tr[N];
int get(int key){
    tr[++idx].key=key;
    tr[idx].size=1;
    tr[idx].val=rand();
    return idx;
}
void pushdown(int u){
    if(tr[u].lazy){
        swap(tr[u].l,tr[u].r);
        tr[tr[u].l].lazy^=1;
        tr[tr[u].r].lazy^=1;
        tr[u].lazy=0;
    }
}
void pushup(int u){
    tr[u].size=tr[tr[u].l].size+tr[tr[u].r].size+1;
}
void spilt(int p,int siz,int &x,int &y){
    if(!p)
    x=y=0;
    else{
        pushdown(p);
        if(tr[tr[p].l].size<siz){
            x=p;
            spilt(tr[p].r,siz-tr[tr[p].l].size-1,tr[p].r,y);
        }
        else{
            y=p;
            spilt(tr[p].l,siz,x,tr[p].l);
        }
        pushup(p);
    }
}
int merge(int x,int y){
    if(!x||!y)
    return x+y;
    if(tr[x].val>=tr[y].val){
        pushdown(x);
        tr[x].r=merge(tr[x].r,y);
        pushup(x);
        return x;
    }
    else{
        pushdown(y);
        tr[y].l=merge(x,tr[y].l);
        pushup(y);
        return y;
    }
}
void reverse(int l,int r){
    spilt(root,l-1,x,y);
    spilt(y,r-l+1,y,z);
    tr[y].lazy^=1;
    root=merge(merge(x,y),z);
}
void vis(int p){
    if(!p)
    return ;
    pushdown(p);
    vis(tr[p].l);
    cout<<tr[p].key<<" ";
    vis(tr[p].r);
}
int main(){
    int i;
    int n;
    int m;
    cin>>n>>m;
    for(i=1;i<=n;i++)
    root=merge(root,get(i));
    while(m--){
        int l,r;
        scanf("%d%d",&l,&r);
        reverse(l,r);
    }
    vis(root);
    return 0;
} 

原文地址:https://www.cnblogs.com/ctyakwf/p/12294058.html

时间: 2024-10-21 02:05:55

fhq-Treap 文艺平衡树代码记录的相关文章

洛谷P3391 【模板】文艺平衡树(Splay)(FHQ Treap)

题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 输入输出格式 输入格式: 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,?n−1,n) m表示翻转操作次数 接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r

[BZOJ3223]文艺平衡树 无旋Treap

3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2--n-1,n)  m表示翻转操作次数接下来m行每行两个数[l,r] 数据保证 1<=l<

平衡树合集(Treap,Splay,替罪羊,FHQ Treap)

今天翻了翻其他大佬的博客,发现自己有些...颓废... 有必要洗心革面,好好学习 序:正常的BST有可能退化,成为链,大大降低效率,所以有很多方法来保持左右size的平衡,本文将简单介绍Treap,Splay,替罪羊,FHQ Treap: 另:代码都是普通平衡树 1.Treap 树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树.其基本操作的期望时间复杂度为O(logn).相对于其他的平衡二叉搜索树,Treap的特点是实现简单,

浅谈fhq treap

一.简介 fhq treap 与一般的treap主要有3点不同 1.不用旋转 2.以merge和split为核心操作,通过它们的组合实现平衡树的所有操作 3.可以可持久化 二.核心操作 代码中val表示节点权值,pri表示节点的优先级,维护小根堆 1.split 将1个treap分裂为两个treap 分裂主要有两种:以权值k作为分界点.以位置k作为分界点 ①以权值k作为分界点 设原来的treap根节点为root,分裂后的<=k的treap A 的根节点为x,>k的treap B 的根节点为y

fhq treap

fhq-treap 小结 粗浅地学习了这个神奇的数据结构,下面瞎写一些感受 首先fhq treap是一个基于分裂与合并的平衡树,那么怎么分裂,怎么合并呢 我们分两种情况考虑 一.权值平衡树(我自己取的名字) 所谓权值平衡树,就是任何操作都只与权值有关的平衡树 比如最基础的分裂,合并操作 分裂就是把平衡树按照权值\(k\)分成两半,一边所有点的权值\(\leq k\),另一边权值\(\gt k\) 怎么分裂呢 首先根据\(treap\)的定义,所有点的权值是一颗二叉搜索树(BST),就是左边比他小

【bzoj1251】序列终结者——fhq treap

Description 给定一个长度为N的序列,每个序列的元素是一个整数.要支持以下三种操作: 1. 将[L,R]这个区间内的所有数加上V. 2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1. 3. 求[L,R]这个区间中的最大值. 最开始所有元素都是0. Input 第一行两个整数N,M.M为操作个数. 以下M行,每行最多四个整数,依次为K,L,R,V.K表示是第几种操作,如果不是第1种操作则K后面只有两个数. Output 对于每个第3种操作,给出正确的回答. Sampl

bzoj3223Tyvj 1729 文艺平衡树

bzoj3223Tyvj 1729 文艺平衡树 题意: 一个数列,支持区间翻转操作. 题解: splay裸题.注意涉及到区间操作的一般用splay不用treap. 代码: 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define fa(x) nds[x].fa 6 #define ch(x,

FHQ Treap小结(神级数据结构!)

首先说一下, 这个东西可以搞一切bst,treap,splay所能搞的东西 pre 今天心血来潮, 想搞一搞平衡树, 先百度了一下平衡树,发现正宗的平衡树写法应该是在二叉查找树的基础上加什么左左左右右左右右的旋转之类的, 思路比较好理解,但是 代码量........ 一看就头大,, 然后,在洛谷翻题解的时候无意间看到了远航之曲发的一篇非常短小精悍的题解, 于是就学了一下 FHQ Treap 这个东西的学名应该是叫做fhq treap,应该是treap的强化版. 整个数据结构中只有两个操作: 1.

平衡树代码总结

这里给出博主的几种平衡树模板代码 vector 代码: // luogu-judger-enable-o2 #include<bits/stdc++.h> #define rd(x) x=read() using namespace std; int n; vector<int>v; inline int read() { int f=1,x=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar