今日内容–线段树
(对于一个数,想将它乘以二就将其左移一位,再想加一就|1)
对于一个数组(大小为N),我们可以通过一个线段树数组(大小约为4N),用来存储其某段区间的信息,例如最大值,区间和。
通常会有build函数,用来建造线段树。
void build(int L, int R, int i) {
tree[i].left = L;
tree[i].right = R;
if (L == R) {
tree[i].sum = arr[L];
return;
}
int mid = (L + R) >> 1;
build(L, mid,i<<1);
build(mid + 1, R, i << 1|1);
pushup(i);
}
modify函数,修改区间信息。
void modify(int ji, int shu, int i) {
if (tree[i].left == ji && tree[i].right == ji) {
tree[i].sum += shu;
return;
}
int mid = tree[i].left + tree[i].right >> 1;
if (ji <= mid) modify(ji, shu, i << 1);
else modify(ji, shu, i << 1 | 1);
pushup(i);
}
query函数,返回区间信息。
int query(int L, int R, int i) {
if (L <= tree[i].left && R >= tree[i].right) return tree[i].sum;
int mid = tree[i].left + tree[i].right >> 1;
int ans = 0;
if (L <= mid) ans += query(L, R, i << 1);
if (R > mid) ans += query(L, R, i << 1|1);
return ans;
}
经典例题:修改单点信息,hdu-1166、最大区间和,SPOJ - GSS1