线段树模板
Posted alessandro
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树模板相关的知识,希望对你有一定的参考价值。
代码
struct Seg {
int l, r, sum, lazy, add;
// lazy == -1: mo dei biao ji
Seg *ch[2];
};
Seg pool[maxn * 3], *pool_pointer(pool);
#define midp ((p->l+p->r)>>1)
inline void update(Seg* p) {
if (p->lazy != -1) {
p->sum = (p->r - p->l) * p->lazy;
} else {
p->sum = p->ch[0]->sum + p->ch[1]->sum + p->add * (p->r - p->l);
}
}
Seg* segTreeBuild(int l, int r) {
Seg* p = pool_pointer + 1;
p->l = l, p->r = r;
if (l + 1 < r) {
p->ch[0] = segTreeBuild(l, midp);
p->ch[1] = segTreeBuild(midp, r);
update(p);
} else {
p->sum = a[l];
p->lazy = -1;
}
return p;
}
void segTreeChangeOne(Seg* p, int pos, int val) {
if (p->l + 1 == p->r) {
p->sum = val;
} else {
if (pos < midp) {
segTreeChangeOne(p->ch[0], pos, val);
} else {
segTreeChangeOne(p->ch[1], pos, val);
}
update(p);
}
}
inline void pushDown(Seg* p) {
if (p->lazy != -1) {
p->ch[0]->lazy = p->lazy;
p->ch[1]->lazy = p->lazy;
update(p->ch[0]);
update(p->ch[1]);
p->lazy = -1;
}
if (p->add > 0) {
p->ch[0]->add += p->add;
p->ch[1]->add += p->add;
update(p->ch[0]);
update(p->ch[1]);
p->add = 0;
}
}
void segTreeChangeRange(Seg* p, int l, int r, int val) {
if (p->l == l && p->r == r) {
p->lazy = val;
p->sum = (r - l) * val;
} else {
pushDown(p);
if (r <= midp) {
segTreeChangeRange(p->ch[0], l, r, val);
} else if (l >= midp) {
segTreeChangeRange(p->ch[1], l, r, val);
} else {
segTreeChangeRange(p->ch[0], l, midp, val), segTreeChangeRange(p->ch[1], midp, r, val);
}
update(p);
}
}
int segTreeSum(Seg* p, int l, int r) {
if (p->l == l && p->r == r) {
return p->sum;
} else {
if (r <= midp) {
return segTreeSum(p->ch[0], l, r);
} else if (l >= midp) {
return segTreeSum(p->ch[1], l, r);
} else {
return segTreeSum(p->ch[0], l, midp) + segTreeSum(p->ch[1], midp, r);
}
}
}
以上是关于线段树模板的主要内容,如果未能解决你的问题,请参考以下文章