2013-team4/code/treap-Persistent
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
const int N = 10010100;
struct Node{
Node *ch[2];
int rank, size;
char c;
void update(){
size = ch[0]->size + ch[1]->size + 1;
}
}pool[N], *null;
int poolCnt;
typedef pair<Node*, Node*> PNN;
Node* newNode(char c){
Node *p = &pool[poolCnt++];
p->ch[0] = p->ch[1] = null;
p->rank = rand();
p->size = 1;
p->c = c;
return p;
}
Node* newNode(Node *a){
Node *p = &pool[poolCnt++];
*p = *a;
return p;
}
// 首先调用 init()
void init(){
poolCnt = 0;
null = newNode('$');
null->size = 0;
}
/* 概率合并可以处理大量 rank 相同的情况, Node 中不需要记录 rank
* double t = double(a->size) / double(a->size + b->size);
* if(rand() < RAND_MAX * t) {...}
* else {...}
*/
// 普通合并, 返回树根
Node* merge(Node *a, Node *b){
if(a == null) return b;
if(b == null) return a;
Node *p;
if(a->rank < b->rank){
p = newNode(a);
p->ch[1] = merge(p->ch[1], b);
}
else{
p = newNode(b);
p->ch[0] = merge(a, p->ch[0]);
}
p->update();
return p;
}
// 将 [1, n] 划分为 [1, k] 和 [k+1, n]
PNN split(Node *a, int k){
if(k == 0) return PNN(null, a);
if(k == a->size) return PNN(a, null);
Node *p = newNode(a);
int lsize = p->ch[0]->size;
if(k <= lsize){
PNN t = split(p->ch[0], k);
p->ch[0] = t.second;
p->update();
return PNN(t.first, p);
}
else{
PNN t = split(p->ch[1], k - lsize - 1);
p->ch[1] = t.first;
p->update();
return PNN(p, t.second);
}
}
// 在第 k 个元素之后进行插入
Node* insert(Node *root, int k, Node *x){
PNN t = split(root, k);
return merge(merge(t.first, x), t.second);
}
// 删除 [l, r] 区间
Node* erase(Node *root, int l, int r){
PNN t = split(root, r);
Node *a = split(t.first, l - 1).first, *b = t.second;
return merge(a, b);
}
}}}
const int N = 10010100;
struct Node{
Node *ch[2];
int rank, size;
char c;
void update(){
size = ch[0]->size + ch[1]->size + 1;
}
}pool[N], *null;
int poolCnt;
typedef pair<Node*, Node*> PNN;
Node* newNode(char c){
Node *p = &pool[poolCnt++];
p->ch[0] = p->ch[1] = null;
p->rank = rand();
p->size = 1;
p->c = c;
return p;
}
Node* newNode(Node *a){
Node *p = &pool[poolCnt++];
*p = *a;
return p;
}
// 首先调用 init()
void init(){
poolCnt = 0;
null = newNode('$');
null->size = 0;
}
/* 概率合并可以处理大量 rank 相同的情况, Node 中不需要记录 rank
* double t = double(a->size) / double(a->size + b->size);
* if(rand() < RAND_MAX * t) {...}
* else {...}
*/
// 普通合并, 返回树根
Node* merge(Node *a, Node *b){
if(a == null) return b;
if(b == null) return a;
Node *p;
if(a->rank < b->rank){
p = newNode(a);
p->ch[1] = merge(p->ch[1], b);
}
else{
p = newNode(b);
p->ch[0] = merge(a, p->ch[0]);
}
p->update();
return p;
}
// 将 [1, n] 划分为 [1, k] 和 [k+1, n]
PNN split(Node *a, int k){
if(k == 0) return PNN(null, a);
if(k == a->size) return PNN(a, null);
Node *p = newNode(a);
int lsize = p->ch[0]->size;
if(k <= lsize){
PNN t = split(p->ch[0], k);
p->ch[0] = t.second;
p->update();
return PNN(t.first, p);
}
else{
PNN t = split(p->ch[1], k - lsize - 1);
p->ch[1] = t.first;
p->update();
return PNN(p, t.second);
}
}
// 在第 k 个元素之后进行插入
Node* insert(Node *root, int k, Node *x){
PNN t = split(root, k);
return merge(merge(t.first, x), t.second);
}
// 删除 [l, r] 区间
Node* erase(Node *root, int l, int r){
PNN t = split(root, r);
Node *a = split(t.first, l - 1).first, *b = t.second;
return merge(a, b);
}