线段树萌新,10pts, AC on #2

P3372 【模板】线段树 1

_ScreamBrother_ @ 2024-11-02 14:01:05

#include <bits/stdc++.h>
#define int long long

const int MAXN = 1e5 + 10;

struct Node {
    int left, right, lazy_tag, sum;
};

std::vector <Node> seg_Tree (MAXN * 4);
std::vector <int> nums (MAXN * 4);
int N, M, x, y, k, op;

int len(int node) { return seg_Tree[node].right - seg_Tree[node].left + 1; }

void build(int left, int right, int node) {
    if (left == right) {
        seg_Tree[node].left = left, seg_Tree[node].right = right;
        seg_Tree[node].sum = nums[left];
        return;
    }

    int mid = (right + left) / 2, lchild = node * 2, rchild = node * 2 + 1;
    build(left, mid, lchild), build(mid + 1, right, rchild);
    seg_Tree[node].sum = seg_Tree[lchild].sum + seg_Tree[rchild].sum;
    seg_Tree[node].left = left, seg_Tree[node].right = right;
}

void push_down(int node) {
    if (seg_Tree[node].lazy_tag) {
        int lchild = node * 2, rchild = node * 2 + 1, le = len(node), lazy;
        seg_Tree[node].sum += (le * (lazy = seg_Tree[node].lazy_tag));
        seg_Tree[lchild].lazy_tag += lazy, seg_Tree[rchild].lazy_tag += lazy;
        int le1 = len(lchild), le2 = len(rchild);
        seg_Tree[lchild].sum += le1 * lazy, seg_Tree[rchild].sum += le2 * lazy;
        seg_Tree[node].lazy_tag = 0;
    }
}

void update(int left, int right, int tag, int node) {
    if (left <= seg_Tree[node].left && seg_Tree[node].right <= right) {
        seg_Tree[node].sum += len(node) * tag;
        seg_Tree[node].lazy_tag += tag;
        return;
    }

    push_down(node);

    int mid = (seg_Tree[node].left + seg_Tree[node].right) / 2;
    if (left <= mid) update(left, right, tag, 2 * node);
    if (mid < right) update(left, right, tag, 2 * node + 1);
    seg_Tree[node].sum = seg_Tree[node * 2].sum + seg_Tree[node * 2 + 1].sum;
}

int query(int left, int right, int node, int ans = 0) {
    if (left <= seg_Tree[node].left && seg_Tree[node].right <= right) 
        return seg_Tree[node].sum;

    push_down(node);

    int mid = (seg_Tree[node].left + seg_Tree[node].right) / 2;
    if (left <= mid) ans += query(left, right, 2 * node);
    if (mid < right) ans += query(left, right, 2 * node + 1);
    return ans;
}

signed main() {
    std::cin >> N >> M;
    for (int i = 1; i <= N; i ++) std::cin >> nums[i];
    build(1, N, 1);

    while (M --) {
        std::cin >> op;
        if (op == 1) {
            std::cin >> x >> y >> k;
            update(x, y, k, 1);
        } else {
            std::cin >> x >> y;
            std::cout << query(x, y, 1) << "\n";
        }
    }

    return 0;
}

|