---
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);
}
}
```