#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 300010
const int INF=1<<30;
int tree[N][2],pa[N],cnt[N],rev[N],val[N];
int Max(int a,int b){ return a>b?a:b; }
class splaytree
{
public:
int Root;
static int idx;
splaytree(){
if(!idx) init();
Root=newnode(-INF);pa[Root]=0;
tree[Root][1]=newnode(INF);pa[tree[Root][1]]=Root;
update(tree[Root][1]);update(Root);
}
void update(int t)
{
//add your code;
cnt[t]=cnt[tree[t][0]]+cnt[tree[t][1]]+1;
}
void push(int t)
{
//add your code;
if(t&&rev[t])
{
swap(tree[t][0],tree[t][1]); rev[t]=0;
if(tree[t][0]) rev[tree[t][0]]^=1;
if(tree[t][1]) rev[tree[t][1]]^=1;
}
}
int newnode(int v){
cnt[++idx]=1;val[idx]=v;
pa[idx]=rev[idx]=tree[idx][0]=tree[idx][1]=0;
return idx;
}
void init()
{
memset(pa,0,sizeof(pa));
memset(rev,0,sizeof(rev));
memset(cnt,0,sizeof(cnt));
memset(tree,0,sizeof(tree));
}
//roate function that support left roate action and right roate action
void rotate(int t)
{
int p=pa[t];
int c=(tree[pa[t]][0]==t);
tree[p][!c]=tree[t][c];
if(tree[t][c]) pa[tree[t][c]]=p;
tree[t][c]=p; pa[t]=pa[p];
if(pa[p])tree[pa[p]][tree[pa[p]][1]==p]=t;
pa[p]=t;update(p);update(t);
}
//the important function that support splay action
void splay(int x,int &head)
{
int p,pp;
while(pa[x]&&x!=head){
p=pa[x];
if(p==head) rotate(x);
else {
pp=pa[p];
if((tree[pp][0]==p)==(tree[p][0]==x))
rotate(p),rotate(x);
else rotate(x),rotate(x);
}
}
if(!pa[x]) head=x;
}
//find node by a value in the tree that root is "head"
int find(int v,int head)
{
int root=head;
while(root)
{
if(v==val[root]) return root;
if(v<val[root]) root=tree[root][0];
if(v>val[root]) root=tree[root][1];
}
return root;
}
int findk(int k,int head)
{
int t;
while(head){
push(head);t=cnt[tree[head][0]];
if(k==t+1) return head;
else if(k<t+1)
head=tree[head][0];
else {
k-=t+1; head=tree[head][1];
}
}
return 0;
}
//find a node that value is v and splay to root
int access(int v,int &head)
{
int root=head;
while(root){
if(val[root]==v) break;
if(val[root]>v)
root=tree[root][0];
else
root=tree[root][1];
}
if(root) splay(root,head); return root;
}
//make a node by value v and insert it
int insert(int v,int &head)
{
int root=head,p=0;
int node=newnode(v);
while(root){
p=root;
if(v<val[root])
root=tree[root][0];
else
root=tree[root][1];
}
if(!p) head=node;
else {
pa[node]=p; tree[p][v>=val[p]]=node;
splay(node,head);
}
return node;
}
//insert a node at the rank k position in the splaytree
int insertk(int k,int v,int &head)
{
int nodek,node=newnode(v);
if(!head){
head=node;update(head);
}
else {
nodek=findk(k,head); splay(nodek,head);
nodek=findk(k+1,head); splay(nodek,tree[head][1]);
tree[nodek][0]=node; pa[node]=nodek;
update(node);update(nodek);update(head);
}
return node;
}
//join two subtree to a biger tree and return the biger tree's root
int join(int a,int b)
{
if(!a) return b; if(!b) return a;
if(!tree[a][1]){
tree[a][1]=b; update(a); return pa[b]=a;
}
if(!tree[b][0]){
tree[b][0]=a; update(b); return pa[a]=b;
}
int right=a;
while(tree[right][1]) right=tree[right][1];
splay(right,a); tree[a][1]=b; update(a);
return pa[b]=a;
}
//find a node that value is v and split it's two childrens to two splay trees
void split(int &head,int node,int &a,int &b)
{
if(node){
splay(node,head);
a=tree[head][0];pa[a]=0;
b=tree[head][1];pa[b]=0;
}
}
//find a node that value is v and remove the node from the tree that root is "head"
void remove(int node,int &head)
{
int l;
if(node)
{
splay(node,head);l=cnt[tree[node][0]];
splay(findk(l,head),head); splay(findk(l+2,head),tree[head][1]);
tree[tree[head][1]][0]=0; update(tree[head][1]); update(head);
}
}
};
int splaytree::idx=0;
void debug(int root)
{
if(!root) return ;
debug(tree[root][0]); printf("%d(%d) ",val[root],root); debug(tree[root][1]);
}
自己写的splay模板
最新推荐文章于 2022-02-24 15:26:19 发布