【模板】主席树
指针版(附加内存池,未封装)
//内存池的定义(注释或删掉即可关闭内存池)
#define memory_pool 1000000
//节点的类
class node {
public:
node* son[2];
int v;
node() {
son[0]=son[1]=NULL;
}
void push_up() {
v=(son[0]?son[0]->v:0)+(son[1]?son[1]->v:0);
}
#ifdef memory_pool
void* operator new(size_t sz);
#endif
};
#ifdef memory_pool
size_t size_node = sizeof(node);
node mem_pool[memory_pool];
node* mem_pos = mem_pool;
void* node::operator new(size_t sz) {
node* p=mem_pos;
mem_pos+=sz/size_node;
return p;
}
/*
//防溢出版
bool end = 0;
void* node::operator new(size_t sz) {
node* p;
if(end) return p = new node[sz/size_node];
if(mem_pos+sz/size_node > &mem_pool[memory_pool-1])return end = 1, p = new node[sz/size_node];
p = mem_pos;
mem_pos += sz/size_node;
return p;
}
*/
#endif
//建立一棵具有所有节点的空树
void build(node* &p, int l, int r) {
if(! p)p = new node;
if(l == r)return;
int mid = (l + r) >> 1;
build(p->son[0], l, mid);
build(p->son[1], mid + 1, r);
}
//建立一棵有部分节点的空树
void build(node* &p, int l, int r, int x, int c) {
if(! p)p = new node;
if(l == r)return void(p->v = c);
int mid = (l + r) >> 1;
if(x <= mid)build(p->son[0], l, mid, x, c);
else build(p->son[1], mid + 1, r, x, c);
p->push_up();
}
//新建一个版本(单点修改)
void update(node* &p, node* rt, int l, int r, int x, int c) {
if(! rt)return build(p, l, r, x, c);
if(! p)p = new node;
if(l == r)return void(p->v = rt->v + c);
int mid = (l + r) >> 1;
if(x <= mid)p->son[1] = rt->son[1], update(p->son[0], rt->son[0], l, mid, x, c);
else p->son[0] = rt->son[0], update(p->son[1], rt->son[1], mid+1, r, x, c);
p->push_up();
}
//区间查询
int query(node* &p,int l,int r,int x,int y) {
if(!p)return 0;
if(l>=x&&r<=y)return p->v;
int mid=(l+r)>>1;
int ans=0;
if(x<=mid)ans+=query(p->son[0],l,mid,x,y);
if(y>mid)ans+=query(p->son[1],mid+1,r,x,y);
return ans;
}