#pragma once
// https://xuzijian629.hatenablog.com/entry/2018/12/08/000452#include"library/math/XorShift.hpp"template<typenameT>classTreap{XorShiftrnd;structNode{Tkey;intpriority;Node*l,*r;Node(Tkey,intpriority=-1):key(key),priority(priority),l(nullptr),r(nullptr){if(priority<0)priority=rnd();}};Node*root=nullptr;usingTree=Node*;// t を key 未満と key 以上に分け、それぞれ l,r に代入voidsplit(Treet,Tkey,Tree&l,Tree&r){if(!t)l=r=nullptr;elseif(t->key<key){// t は l の担当l=t;split(t->r,key,t->r,r);}else{r=t;split(t->l,key,l,t->l);}}// t に item を挿入voidinsert(Tree&t,Treeitem){if(!t)t=item;elseif(item->priority>t->priority){// t の場所に item を置く// t とその部分木 は item の左右にくっつけるsplit(t,item->key,item->l,item->r);t=item;}elseinsert(item->key<t->key?t->l:t->r,item);}//voidmerge(Tree&t,Treel,Treer){if(!lor!r)t=l?l:r;elseif(l->priority>r->priority){merge(l->r,l->r,r);t=l;}else{merge(r->l,l,r->l);t=r;}}voiderase(Tree&t,Tkey){if(t->key==key)merge(t,t->l,t->r);elseerase(key<t->key?t->l:t->r,key);}boolfind(Tree&t,Tkey){if(!t)returnfalse;if(t->key==key)returntrue;returnfind(key<t->key?t->l:t->r,key);}public:voidinsert(Tkey){insert(root,newNode(key));}voiderase(Tkey){erase(root,key);}boolfind(Tkey){returnfind(root,key);}};
#line 2 "library/datastructure/binary_search_tree/Treap.hpp"
// https://xuzijian629.hatenablog.com/entry/2018/12/08/000452#line 1 "library/math/XorShift.hpp"
classXorShift{uint64_tx;public:XorShift(){mt19937rnd(chrono::steady_clock::now().time_since_epoch().count());x=rnd();for(inti=0;i<100;i++)(*this)();}uint64_toperator()(){x=x^(x<<7);returnx=x^(x>>9);}};#line 4 "library/datastructure/binary_search_tree/Treap.hpp"
template<typenameT>classTreap{XorShiftrnd;structNode{Tkey;intpriority;Node*l,*r;Node(Tkey,intpriority=-1):key(key),priority(priority),l(nullptr),r(nullptr){if(priority<0)priority=rnd();}};Node*root=nullptr;usingTree=Node*;// t を key 未満と key 以上に分け、それぞれ l,r に代入voidsplit(Treet,Tkey,Tree&l,Tree&r){if(!t)l=r=nullptr;elseif(t->key<key){// t は l の担当l=t;split(t->r,key,t->r,r);}else{r=t;split(t->l,key,l,t->l);}}// t に item を挿入voidinsert(Tree&t,Treeitem){if(!t)t=item;elseif(item->priority>t->priority){// t の場所に item を置く// t とその部分木 は item の左右にくっつけるsplit(t,item->key,item->l,item->r);t=item;}elseinsert(item->key<t->key?t->l:t->r,item);}//voidmerge(Tree&t,Treel,Treer){if(!lor!r)t=l?l:r;elseif(l->priority>r->priority){merge(l->r,l->r,r);t=l;}else{merge(r->l,l,r->l);t=r;}}voiderase(Tree&t,Tkey){if(t->key==key)merge(t,t->l,t->r);elseerase(key<t->key?t->l:t->r,key);}boolfind(Tree&t,Tkey){if(!t)returnfalse;if(t->key==key)returntrue;returnfind(key<t->key?t->l:t->r,key);}public:voidinsert(Tkey){insert(root,newNode(key));}voiderase(Tkey){erase(root,key);}boolfind(Tkey){returnfind(root,key);}};