---
# System prepended metadata

title: treap
tags: [codebook]

---

---
tags: codebook
---
{%hackmd theme-dark %}
# treap

## persistent
```cpp=
#include<random>
mt19937 mt(hash<string>()(":poop:"));
struct node{
    int p,v;ll val,sum;
    node *l,*r;
    node(int x=0,ll y=0):p(x),v(mt()),val(y),sum(y){
        l=r=nullptr;
    }
    node(node* cur){*this=*cur;}
    void pull(){
        sum=val;
        for(auto i:{l,r})
            if(i) sum+=i->sum;
    }
}pool[maxn],*ptr=&pool[0];
node* merge(node* a,node* b){
    if(!a||!b) return new(ptr++) node(a?:b);
    if(a->v<b->v){
        node* ret=new(ptr++) node(a);
        ret->r=merge(a->r,b),ret->pull();
        return ret;
    }else{
        node* ret=new(ptr++) node(b);
        ret->l=merge(a,b->l),ret->pull();
        return ret;
    }
}
P<node*> split(node* cur,int k){
    if(!cur) return {nullptr,nullptr};
    node* ret=new(ptr++) node(cur);
    if(cur->p<k){
        auto [a,b]=split(cur->r,k);
        ret->r=a,ret->pull();
        return {ret,b};
    }else{
        auto [a,b]=split(cur->l,k);
        ret->l=b,ret->pull();
        return {a,ret};
    }
}
```

## with lazy propagation
```cpp=
#include<random>
mt19937 mt(hash<string>()(":poop:"));
struct node{
    int p,v,sz; ll val,sum,inc,set;
    node *l,*r;
    node(int x,ll y):p(x),v(mt()),sz(1),val(y),sum(y),inc(0),set(LINF){
        l=r=nullptr;
    }
    void pull(){
        sz=1;
        for(auto i:{l,r})
            if(i) sz+=i->sz;
        sum=val;
        for(auto i:{l,r}){
            if(!i) continue;
            if(i->set!=LINF)
                sum+=i->set*i->sz;
            else
                sum+=i->sum;
            if(i->inc)
                sum+=i->inc*i->sz;
        }
    }
    void push(){
        if(set!=LINF){
            sum=set*sz,val=set;
            for(auto i:{l,r})
                if(i) i->inc=0,i->set=set;
            set=LINF;
        }
        if(inc){
            sum+=inc*sz,val+=inc;
            for(auto i:{l,r})
                if(i) i->inc+=inc;
            inc=0;
        }
    }
};
node* merge(node* a,node* b){
    if(!a||!b) return a?:b; 
    a->push(),b->push();
    if(a->v<b->v)
        return a->r=merge(a->r,b),a->pull(),a;
    return b->l=merge(a,b->l),b->pull(),b;
}
void split(node* cur,int k,node*& a,node*& b){
    if(!cur){a=b=nullptr;return;}
    cur->push();
    if(cur->p<k)
        a=cur,split(a->r,k,a->r,b),a->pull();
    else
        b=cur,split(b->l,k,a,b->l),b->pull();
}
```

## split by size
```cpp=
#include<random>
mt19937 mt(hash<string>()(":poop:"));
struct node{
    int v,sz; char val;
    node *l,*r;
    node(char ch):v(mt()),sz(1),val(ch){
        l=r=nullptr;
    }
    void pull(){
        sz=1;
        for(auto i:{l,r})
            if(i) sz+=i->sz;
    }
};
node* merge(node* a,node* b){
    if(!a||!b) return a?:b; 
    if(a->v<b->v)
        return a->r=merge(a->r,b),a->pull(),a;
    return b->l=merge(a,b->l),b->pull(),b;
}
inline int size(node* p){return p?p->sz:0;};
void split(node* cur,int k,node*& a,node*& b){
    if(!cur){a=b=nullptr;return;}
    if(size(cur->l)+1<=k)
        a=cur,split(a->r,k-size(cur->l)-1,a->r,b),a->pull();
    else
        b=cur,split(b->l,k,a,b->l),b->pull();
}
```


## old

```cpp=
//#include"iostreambuf"
#include<iostream>
#include<vector>
#include<random>
#define size_t unsigned
using namespace std;
mt19937 rd;
template<typename T>
struct treap{
    struct node{
        using nptr=node*;
        T k;int v;nptr l,r;
        node(const T& x):k(x),v(rd()){l=r=nullptr;}
    } *root;
    using nptr=node*;
    void print(ostream& os,nptr cur){
        if(!cur) return;
        print(os,cur->l);
        os<<cur->k<<' ';
        print(os,cur->r);
    }
    void print(ostream& os){print(os,root);}
    nptr merge(nptr a,nptr b){
        if(!a) return b;
        if(!b) return a;
        if(a->v<b->v){
            a->r=merge(a->r,b);return a;
        }else{
            b->l=merge(a,b->l);return b;}
    } 
    treap merge(treap b){
        root=merge(root,b.root);return *this;
    }
    void split(nptr cur,const T& x,nptr& a,nptr& b){
        if(!cur){a=b=nullptr;return;}
        if(cur->k<x)
            a=cur,split(a->r,x,a->r,b);
        else
            b=cur,split(b->l,x,a,b->l);
    }
    auto split(const T& x){
        treap a,b;
        split(root,x,a.root,b.root);
        return make_pair(a,b);
    }
    void insert(const T& x){
        nptr l,m,r;
        split(root,x,l,r);
        split(r,x+1,m,r);
        root=merge(merge(l,new node(x)),r);
    }
    void erase(const T& x){
        nptr l,m,r;
        split(root,x,l,r);
        split(r,x+1,m,r);
        root=merge(l,r);
    }
    bool count(const T& x,node* cur){
        if(!cur) return false;
        else if(cur->v==x) return true;
        else return count(x,(x<cur->k?cur->l:cur->r));
    } 
    bool count(const T& x){return count(x,root);}
    treap(const vector<T>& v={}):root(nullptr){
        for(const auto& i:v)
            insert(i);
    }
};
template<typename T>
ostream& operator<<(ostream& os,treap<T> t){
    t.print(os);return os;
}
int main(){
	cin.tie(nullptr);cout.tie(nullptr);
	ios::sync_with_stdio(false);
	treap<int> tree;
	for(int n=0;n!=1e5;n++)
		tree.insert(n);
	cout<<tree<<endl;
	return 0;
}
```

## toxic ver
```cpp=
#include"./template/template.hpp"

//#define MULTI_TASKCASE
using namespace rit;
using namespace wit;
using namespace abb;
using namespace output;

inline void init() {

}

mt19937 mt;
constexpr int maxn=1e5;
static int k[maxn],v[maxn],l[maxn],r[maxn],top=0;

inline node(int x){
    k[top]=x,v[top]=mt();
    l[top]=r[top]=-1;
    return top++;
}

int merge(int a,int b){
    int rt=-1,*cur=&rt;
    while(~a&&~b){
        if(v[a]<v[b])
            *cur=a,cur=&r[a],a=r[a];
        else
            *cur=b,cur=&l[b],b=l[b];
    }
    *cur=~a?a:b;
    return rt;
}

void split(int t,int x,int *a,int *b){
    while(~t){
        if(k[t]<x)
            t=r[*a=t],a=&r[*a];
        else
            t=l[*b=t],b=&l[*b];
    }
    *a=*b=-1;
}

void insert(int& t,int x){
    int l,r;
    split(t,x,&l,&r);
    t=merge(merge(l,node(x)),r);
}

void print(int t){
    if(!~t) return;
    print(l[t]);
    cout<<k[t]<<' ';
    print(r[t]);
}

inline void solve() {
    int tree=-1;
    for(auto i:{1,5,4,2,0,3,6,9,7,8}){
        insert(tree,i);
        // for(int i=0;i<top;i++)
        //     cout<<'('<<k[i]<<' '<<l[i]<<' '<<r[i]<<')';
        // cout<<endl;
    }
    print(tree);
}

main() {
    // ios::sync_with_stdio(false);
    init();
    int t = 1;
#ifdef MULTI_TASKCASE
    cin >> t; cin.ignore();
#endif
    while (t--) solve();
    return 0;
}
```

## return value split

```cpp=
mt19937 mt(hash<string>()(":poop:"));
struct node {
	node *l, *r;
	int p, v; ll val, minval;
	node(int x, ll y): p(x), v(mt()), val(y), minval(y) {
		l = r = nullptr;
	}
	node* pull() {
		minval = val;
		for (auto i : {l, r})
			if (i) minval = min(minval, i->minval);
		return this;
	}
};
node* merge(node* a, node* b) {
	if (!a || !b) return a ? : b;
	if (a->v < b->v)
		return a->r = merge(a->r, b), a->pull();
	else
		return b->l = merge(a, b->l), b->pull();
}
P<node*> split(node* p, int k) {
	if (!p) return {nullptr, nullptr};
	if (p->p < k) {
		// a = p, split(a->r, k, a->r, b), a->pull();
		auto [x, y] = split(p->r, k);
		p->r = x, p->pull();
		return {p, y};
	}
	else {
		// b = p, split(b->l, k, a, b->l), b->pull();
		auto [x, y] = split(p->l, k);
		p->l = y, p->pull();
		return {x, p};
	}
}
inline void solve() {
	int n, q, k; cin >> n >> q;
	node* root = nullptr;
	for (int i = 0; i < n; i++)
		cin >> k, root = merge(root, new node(i, k));
	while (q--) {
		int op, a, b;
		node *l, *m, *r;
		switch (cin >> op >> a >> b, op) {
		case 1:
			tie(l, r) = split(root, a);
			tie(l, m) = split(l, a - 1);
			m->val = b, m->pull();
			break;
		case 2:
			tie(l, r) = split(root, b);
			tie(l, m) = split(l, a - 1);
			cout << m->minval << endl;
		}
		root = merge(merge(l, m), r);
	}
}
```