动态开点的方法在上一篇blog中,不赘述。
动态开点的线段树也是一个线段树,也可以完成普通线段树的区间查询,也可以采用懒标记的方法区间修改。但是需要注意的是,在查询或者修改的函数中,需要将根节点代表的区间写入形参。根据参数中的根区间确定子区间。
虽然很鸡肋,多学一点是一点。
#include <bits/stdc++.h>
#define lson(k) c[k].lson
#define rson(k) c[k].rson
#define sum(a, b) a + b
using namespace std;
const int N = 310;
struct p{
int lson, rson, sum, lazy;
};
int cnt;
p c[N * 4];
void init(){
cnt = 0;
}
int build(){
++cnt;
c[cnt].lson = -1;
c[cnt].rson = -1;
c[cnt].lazy = 0;
c[cnt].sum = 0;
return cnt;
}
void update(int ind, int k, int l, int r, int val){
if (l == r){
c[k].sum = val;
return;
}
int mid = (l + r) >> 1;
if (ind <= mid){
if (c[k].lson == -1)c[k].lson = build();
update(ind, c[k].lson, l, mid, val);
}
else{
if (c[k].rson == -1)c[k].rson = build();
update(ind, c[k].rson, mid + 1, r, val);
}
c[k].sum = sum(c[k].lson == -1 ? -1 : c[c[k].lson].sum, c[k].rson == -1 ? -1 : c[c[k].rson].sum);
}
void down(int k){
if (c[k].lazy){
if (lson(k) == -1){
lson(k) = build();
}
if (rson(k) == -1){
rson(k) = build();
}
c[lson(k)].lazy += c[k].lazy;
c[rson(k)].lazy += c[k].lazy;
}
}
int query(int ll, int rr, int l, int r, int k){
if (ll <= l && rr >= r){
return c[k].sum;
}
int res = 0;
int mid = (l + r) >> 1;
if (c[k].lazy){
down(k);
c[lson(k)].sum += c[k].lazy * (mid - l + 1);
c[rson(k)].sum += c[k].lazy * (r - mid);
c[k].lazy = 0;
}
if (ll <= mid){
if (c[k].lson == -1)c[k].lson = build();
res = sum(res, query(ll, rr, l, mid, c[k].lson));
}
if (rr > mid){
if (c[k].rson == -1)c[k].rson = build();
res = sum(res, query(ll, rr, mid + 1, r, c[k].rson));
}
return res;
}
void update(int ll, int rr, int l, int r, int k, int d){
if (ll <= l && rr >= r){
c[k].sum += d * (r - l + 1);
c[k].lazy += d;
return;
}
int mid = (l + r) >> 1;
if (c[k].lazy){
down(k);
c[lson(k)].sum += c[k].lazy * (mid - l + 1);
c[rson(k)].sum += c[k].lazy * (r - mid);
c[k].lazy = 0;
}
if (ll <= mid){
if (lson(k) == -1){
lson(k) = build();
}
update(ll, rr, l, mid, lson(k), d);
}
if (rr > mid){
if (rson(l) == -1){
rson(k) = build();
}
update(ll, rr, mid + 1, r, rson(k), d);
}
c[k].sum = sum(c[lson(k)].sum, c[rson(k)].sum);
}
int main(){
int root = build();
update(1, 5, 1, 10, root, 1);
update(6, 10, 1, 10, root, 2);
update(3, 7, 1, 10, root, -1);
int res = query(1, 10, 1, 10, root);
printf("%d\n", res);
return 0;
}