Last active
April 25, 2016 07:59
-
-
Save jacky860226/9e8e3001a568b0523716ac5d57e7b294 to your computer and use it in GitHub Desktop.
[Split / Merge] Randomized Binary Search Tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*需要再node裡面增加tag跟ma用來儲存區間增加量跟最大值*/ | |
int ask(node *&o,int l,int r){ | |
/*在o子樹詢問區間[l,r]的最大值*/ | |
node *a,*b,*c; | |
split(o,a,b,l-1); | |
split(b,b,c,r-l+1); | |
b->down();/*記得要先將懶惰標記下推*/ | |
int ans=b->ma; | |
o=merge(a,merge(b,c)); | |
return ans; | |
} | |
int add(node *&o,int l,int r,int v){ | |
/*在o子樹將區間[l,r]的值都加上v*/ | |
node *a,*b,*c; | |
split(o,a,b,l-1); | |
split(b,b,c,r-l+1); | |
b->tag+=v; | |
o=merge(a,merge(b,c)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node *merge(node *a,node *b){ | |
if(!a||!b)return a?a:b; | |
static int x; | |
if(x++%(a->s+b->s)<a->s){ | |
a->down(); | |
a->r=merge(a->r,b); | |
a->up(); | |
return a; | |
}else{ | |
b->down(); | |
b->l=merge(a,b->l); | |
b->up(); | |
return b; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct node{ | |
T data; | |
int s; | |
//可以再加入其他維護值(max,min等等)做區間處理用 | |
node *l,*r; | |
node(const T &d):data(d),s(1),l(0),r(0){} | |
inline void up(){ | |
s=1; | |
if(l)s+=l->s; | |
if(r)s+=r->s; | |
} | |
inline void down(){ | |
//這邊是放作區間維護需要的更新(懶惰標記下推) | |
//(min,max,是否反轉區間....等等) | |
//本範例只提供最基本的處理 | |
} | |
}*root; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline int ran(){ | |
static int x=20160425; | |
return (x=0xdefaced*x+1)&INT_MAX; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline int rank(const T &data){ | |
//使用前必須保證整顆樹是BST | |
//否則會run time error | |
node *p=root; | |
int cnt=0; | |
while(p){ | |
if(data<=p->data)p=p->l; | |
else cnt+=size(p->l)+1,p=p->r; | |
} | |
return cnt; | |
} | |
inline void insert(const T &data,int k){ | |
//在第k個位置之前插入data | |
node *a,*b,*now; | |
split(root,a,b,k); | |
now=new node(data); | |
a=merge(a,now); | |
root=merge(a,b); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline int size(node *o){ | |
return o?o->s:0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void split(node *o,node *&a,node *&b,int k){ | |
if(!o)a=b=0; | |
else{ | |
o->down(); | |
if(k<=size(o->l)){ | |
b=o; | |
split(o->l,a,b->l,k); | |
}else{ | |
a=o; | |
split(o->r,a->r,b,k-size(o->l)-1); | |
} | |
o->up(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline void up(){ | |
size=1; | |
ma=data; | |
if(l){ | |
s+=l->s; | |
ma=max(ma,l->ma+l->tag); | |
} | |
if(r){ | |
s+=r->s; | |
ma=max(ma,r->ma+r->tag); | |
} | |
} | |
inline void down(){ | |
data+=tag; | |
if(l)l->tag+=tag; | |
if(r)r->tag+=tag; | |
tag=0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment