线段树的板子题

线段树支持单点修改,单点查询,区间修改,区间查询
pushup:子节点更新父节点
pushdown:把懒标记向下传
build:初始化一颗树
modify:修改一个区间
query:查询一个区间

线段树的完整代码

AcWing 243. 一个简单的整数问题2 链接:https://www.acwing.com/problem/content/244/

#include <cstdio>
const int N = 100010;
typedef long long LL;

int w[N], m, n;
struct Node {
    int l, r;
    LL sum, add;
} tr[4 * N];

void pushup(int u) {
    tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}

void pushdown(int u) {
    Node &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
    if (root.add) {
        left.add += root.add, left.sum += (left.r - left.l + 1ll) * root.add;
        right.add += root.add, right.sum += (right.r - right.l + 1ll) * root.add;
        root.add = 0;
    }
}

void build(int u, int l, int r) {
    if (l == r) {
        tr[u] = {l, r, w[l], 0};
    } else {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}
void modify(int u, int l, int r, int d) {
    if (tr[u].l >= l && tr[u].r <= r) {
        tr[u].sum += (tr[u].r - tr[u].l + 1ll) * d;
        tr[u].add += d;
    } else {
        // 此时是需要分裂修改了,需要pushdown一下
        pushdown(u);
        int mid = tr[u].r + tr[u].l >> 1;
        if (l <= mid)
            modify(u << 1, l, r, d);
        if (r > mid)
            modify(u << 1 | 1, l, r, d);
        pushup(u);
    }
}

LL query(int u, int l, int r) {
    if (tr[u].l >= l && tr[u].r <= r)
        return tr[u].sum;

    // 查询了,也是分裂查询,先pushdown一下
    pushdown(u);

    int mid = tr[u].l + tr[u].r >> 1;
    LL sum = 0;
    if (l <= mid)
        sum += query(u << 1, l, r);
    if (r > mid)
        sum += query(u << 1 | 1, l, r);
    return sum;
}

int main() {

    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &w[i]);

    build(1, 1, n);

    char op[2];
    int l, r, d;
    while (m--) {
        scanf("%s", op);
        if (op[0] == 'Q') {
            scanf("%d%d", &l, &r);
            printf("%lld\n", query(1, l, r));
        } else {
            scanf("%d%d%d", &l, &r, &d);
            modify(1, l, r, d);
        }
    }
    return 0;
}
posted @ 2024-04-13 21:59  喝茶看猴戏  阅读(10)  评论(0)    收藏  举报