This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub ttamx/cp-library
#include "data-structure/link-cut-tree/splay-tree-base.hpp"
#pragma once /** * Author: Teetat T. * Date: 2024-04-13 * Description: Splay Tree. splay(u) will make node u be the root of the tree in amortized O(log n) time. */ template<class Node> struct SplayTreeBase{ using Ptr = Node*; bool is_root(Ptr t){ return !(t->p)||(t->p->l!=t&&t->p->r!=t); } // The parent of the root stores the path parant in link cut tree. int size(Ptr t){ return t?t->size:0; } virtual void push(Ptr t){}; virtual void pull(Ptr t){}; int pos(Ptr t){ if(t->p){ if(t->p->l==t)return -1; if(t->p->r==t)return 1; } return 0; } void rotate(Ptr t){ Ptr x=t->p,y=x->p; if(pos(t)==-1){ if((x->l=t->r))t->r->p=x; t->r=x,x->p=t; }else{ if((x->r=t->l))t->l->p=x; t->l=x,x->p=t; } pull(x),pull(t); if((t->p=y)){ if(y->l==x)y->l=t; if(y->r==x)y->r=t; } } void splay(Ptr t){ if(!t)return; push(t); while(!is_root(t)){ Ptr x=t->p; if(is_root(x)){ push(x),push(t); rotate(t); }else{ Ptr y=x->p; push(y),push(x),push(t); if(pos(x)==pos(t))rotate(x),rotate(t); else rotate(t),rotate(t); } } } Ptr get_first(Ptr t){ while(t->l)push(t),t=t->l; splay(t); return t; } Ptr get_last(Ptr t){ while(t->r)push(t),t=t->r; splay(t); return t; } Ptr merge(Ptr l,Ptr r){ splay(l),splay(r); if(!l)return r; if(!r)return l; l=get_last(l); l->r=r; r->p=l; pull(l); return l; } pair<Ptr,Ptr> split(Ptr t,int k){ if(!t)return {nullptr,nullptr}; if(k==0)return {nullptr,t}; if(k==size(t))return {t,nullptr}; push(t); if(k<=size(t->l)){ auto x=split(t->l,k); t->l=x.second; t->p=nullptr; if(x.second)x.second->p=t; pull(t); return {x.first,t}; }else{ auto x=split(t->r,k-size(t->l)-1); t->r=x.first; t->p=nullptr; if(x.first)x.first->p=t; pull(t); return {t,x.second}; } } void insert(Ptr &t,int k,Ptr v){ splay(t); auto x=split(t,k); t=merge(merge(x.first,v),x.second); } void erase(Ptr &t,int k){ splay(t); auto x=split(t,k); auto y=split(x.second,1); // delete y.first; t=merge(x.first,y.second); } template<class T> Ptr build(const vector<T> &v){ if(v.empty())return nullptr; function<Ptr(int,int)> build=[&](int l,int r){ if(l==r)return new Node(v[l]); int m=(l+r)/2; return merge(build(l,m),build(m+1,r)); }; return build(0,v.size()-1); } };
#line 2 "data-structure/link-cut-tree/splay-tree-base.hpp" /** * Author: Teetat T. * Date: 2024-04-13 * Description: Splay Tree. splay(u) will make node u be the root of the tree in amortized O(log n) time. */ template<class Node> struct SplayTreeBase{ using Ptr = Node*; bool is_root(Ptr t){ return !(t->p)||(t->p->l!=t&&t->p->r!=t); } // The parent of the root stores the path parant in link cut tree. int size(Ptr t){ return t?t->size:0; } virtual void push(Ptr t){}; virtual void pull(Ptr t){}; int pos(Ptr t){ if(t->p){ if(t->p->l==t)return -1; if(t->p->r==t)return 1; } return 0; } void rotate(Ptr t){ Ptr x=t->p,y=x->p; if(pos(t)==-1){ if((x->l=t->r))t->r->p=x; t->r=x,x->p=t; }else{ if((x->r=t->l))t->l->p=x; t->l=x,x->p=t; } pull(x),pull(t); if((t->p=y)){ if(y->l==x)y->l=t; if(y->r==x)y->r=t; } } void splay(Ptr t){ if(!t)return; push(t); while(!is_root(t)){ Ptr x=t->p; if(is_root(x)){ push(x),push(t); rotate(t); }else{ Ptr y=x->p; push(y),push(x),push(t); if(pos(x)==pos(t))rotate(x),rotate(t); else rotate(t),rotate(t); } } } Ptr get_first(Ptr t){ while(t->l)push(t),t=t->l; splay(t); return t; } Ptr get_last(Ptr t){ while(t->r)push(t),t=t->r; splay(t); return t; } Ptr merge(Ptr l,Ptr r){ splay(l),splay(r); if(!l)return r; if(!r)return l; l=get_last(l); l->r=r; r->p=l; pull(l); return l; } pair<Ptr,Ptr> split(Ptr t,int k){ if(!t)return {nullptr,nullptr}; if(k==0)return {nullptr,t}; if(k==size(t))return {t,nullptr}; push(t); if(k<=size(t->l)){ auto x=split(t->l,k); t->l=x.second; t->p=nullptr; if(x.second)x.second->p=t; pull(t); return {x.first,t}; }else{ auto x=split(t->r,k-size(t->l)-1); t->r=x.first; t->p=nullptr; if(x.first)x.first->p=t; pull(t); return {t,x.second}; } } void insert(Ptr &t,int k,Ptr v){ splay(t); auto x=split(t,k); t=merge(merge(x.first,v),x.second); } void erase(Ptr &t,int k){ splay(t); auto x=split(t,k); auto y=split(x.second,1); // delete y.first; t=merge(x.first,y.second); } template<class T> Ptr build(const vector<T> &v){ if(v.empty())return nullptr; function<Ptr(int,int)> build=[&](int l,int r){ if(l==r)return new Node(v[l]); int m=(l+r)/2; return merge(build(l,m),build(m+1,r)); }; return build(0,v.size()-1); } };