以下是一份简单的线段树代码,实现区间求和和区间修改:

const int MAXN = 1e5 + 5;

int n, q;
int a[MAXN];
int tree[MAXN << 2], lazy[MAXN << 2];

void build(int node, int left, int right) {
    if (left == right) {
        tree[node] = a[left];
        return;
    }
    int mid = (left + right) >> 1;
    build(node << 1, left, mid);
    build(node << 1 | 1, mid + 1, right);
    tree[node] = tree[node << 1] + tree[node << 1 | 1];
}

void pushdown(int node, int left, int right) {
    if (lazy[node]) {
        int mid = (left + right) >> 1;
        tree[node << 1] += lazy[node] * (mid - left + 1);
        tree[node << 1 | 1] += lazy[node] * (right - mid);
        lazy[node << 1] += lazy[node];
        lazy[node << 1 | 1] += lazy[node];
        lazy[node] = 0;
    }
}

void update(int node, int left, int right, int l, int r, int val) {
    if (left > r || right < l) return;
    if (left >= l && right <= r) {
        tree[node] += val * (right - left + 1);
        lazy[node] += val;
        return;
    }
    pushdown(node, left, right);
    int mid = (left + right) >> 1;
    update(node << 1, left, mid, l, r, val);
    update(node << 1 | 1, mid + 1, right, l, r, val);
    tree[node] = tree[node << 1] + tree[node << 1 | 1];
}

int query(int node, int left, int right, int l, int r) {
    if (left > r || right < l) return 0;
    if (left >= l && right <= r) return tree[node];
    pushdown(node, left, right);
    int mid = (left + right) >> 1;
    return query(node << 1, left, mid, l, r) + query(node << 1 | 1, mid + 1, right, l, r);
}

int main() {
    scanf("%d%d", &n, &q);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    build(1, 1, n);
    while (q--) {
        int op, l, r, val;
        scanf("%d%d%d", &op, &l, &r);
        if (op == 1) {
            scanf("%d", &val);
            update(1, 1, n, l, r, val);
        } else {
            printf("%d\n", query(1, 1, n, l, r));
        }
    }
    return 0;
}

其中 tree 数组表示线段树的节点值,lazy 数组表示懒标记。build 函数用于建树,update 函数用于区间修改,query 函数用于区间查询。在 update 函数中,先判断当前节点是否需要下传懒标记,然后递归修改左右子树,并更新当前节点的值。在 query 函数中同样需要先判断当前节点是否需要下传懒标记,然后递归查询左右子树并返回结果。

C++ 线段树代码示例:区间求和与修改

原文地址: http://www.cveoy.top/t/topic/jCpS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录