为什么用线段树做线段树板子题会T
  • 板块灌水区
  • 楼主Wrong_Accept
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/25 14:58
  • 上次更新2024/7/25 15:00:53
查看原帖
为什么用线段树做线段树板子题会T
977599
Wrong_Accept楼主2024/7/25 14:58

RT,这是提交记录。

Code

#include <bits/stdc++.h>

std::vector<long long> a, tree, tag;

int ls(int p) { return (p << 1) + 1; }

int rs(int p) { return (p << 1) + 2; }

void build(int l, int r, int p = 0) {
    if (l == r)
        tree.at(p) = a.at(l);
    else {
        const int mid = l + r >> 1;
        build(l, mid, ls(p));
        build(mid + 1, r, rs(p));
        tree.at(p) = tree.at(ls(p)) + tree.at(rs(p));
    }
}

long long find(int l, int r, int pl, int pr, int p = 0) {
    if (l <= pl && r >= pr)
        return tree.at(p);
    const int mid = pl + pr >> 1;
    if (tag.at(p)) {
        tree.at(ls(p)) += tag.at(p) * (mid - pl + 1);
        tree.at(rs(p)) += tag.at(p) * (pr - mid);
        tag.at(ls(p)) += tag.at(p);
        tag.at(rs(p)) += tag.at(p);
        tag.at(p) = 0;
    }
    long long res = 0;
    if (l <= mid)
        res += find(l, r, pl, mid, ls(p));
    if (r > mid)
        res += find(l, r, mid + 1, pr, rs(p));
    return res;
}

void modify(int l, int r, int x, int pl, int pr, int p = 0) {
    std::cerr << l << ' ' << r << ' ' << pl << ' ' << pr << '\n';
    if (l <= pl && r >= pr) {
        tree.at(p) += x * (pr - pl + 1);
        tag.at(p) += x;
    } else {
        const int mid = pl + pr >> 1;
        if (tag.at(p)) {
            tree.at(ls(p)) += tag.at(p) * (mid - pl + 1);
            tree.at(rs(p)) += tag.at(p) * (pr - mid);
            tag.at(ls(p)) += tag.at(p);
            tag.at(rs(p)) += tag.at(p);
            tag.at(p) = 0;
        }
        if (l <= mid)
            modify(l, r, x, pl, mid, ls(p));
        if (r > mid)
            modify(l, r, x, mid + 1, pr, rs(p));
        tree.at(p) = tree.at(ls(p)) + tree.at(rs(p));
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int n, m;
    std::cin >> n >> m;
    a.resize(n);
    tree.resize(n << 2);
    tag.resize(n << 2);
    for (long long &v : a)
        std::cin >> v;
    build(0, n - 1);
    while (m--) {
        int tp, x, y;
        std::cin >> tp >> x >> y;
        if (tp == 1) {
            int k;
            std::cin >> k;
            modify(x - 1, y - 1, k, 0, n - 1);
        } else
            std::cout << find(x - 1, y - 1, 0, n - 1) << std::endl;
    }

    return 0;
}
2024/7/25 14:58
加载中...