萌新求助线段树
查看原帖
萌新求助线段树
418601
Typed_SIGTERM楼主2024/10/26 08:23

输出 11 8 16,不知道哪里错了 /kk

#include <iostream>
using namespace std;

namespace Solution {
using LL = long long;
constexpr int N = 1e5 + 5, NODE = N << 2; // 线段树是完全二叉树,节点数 < 深度 * 4
int n;
LL a[N], tree[NODE], flag[NODE];

void dbg() {
  cerr << "tree: ";
  for (int i = 1; i < n * 2; ++i) cerr << tree[i] << ' ';
  cerr << "\nflag: ";
  for (int i = 1; i < n * 2; ++i) cerr << flag[i] << ' ';
  cerr << '\n';
}

inline int left(int x) { return x << 1; }
inline int right(int x) { return (x << 1) + 1; }

void pushDown(int root, int l, int r) {
  cerr << "push " << root << ' ' << l << ' ' << r << '\n';
  if (!flag[root]) return;
  tree[root] += flag[root] * (r - l + 1); // [l, r] 区间内都加了 flag[root]
  if (l != r) { // 需要下发标记
    flag[left(root)] += flag[root];
    flag[right(root)] += flag[root];
  }
  flag[root] = 0;
}

inline void pushUp(int x) {
  tree[x] = tree[left(x)] + tree[right(x)];
}

void build(int root, int l, int r) {
  if (l == r) {
    tree[root] = a[l];
  } else {
    int mid = (l + r) >> 1;
    build(left(root), l, mid);
    build(right(root), mid + 1, r);
    pushUp(root);
  }
}

void update(int l, int r, LL value, int root = 1, int start = 1, int end = n) {
  cerr << "update " << l << '~' << r << ", " << value << ", " << root << ", " << start << '~' << end << '\n';
  if (l <= start && r >= end) {
    // @todo optimize
    tree[root] += value * (end - start + 1);
    flag[root] += value;
   } else {
    pushDown(root, start, end);
    int mid = (start + end) >> 1;
    if (l <= mid)
      update(l, r, value, left(root), start, mid);
    if (r > mid)
      update(l, r, value, right(root), mid + 1, end);
    pushUp(root);
  }
  dbg();
}

LL query(int l, int r, int root = 1, int start = 1, int end = n) {
  cerr << "query\n";
  if (l <= start && r >= end) return tree[root];
  pushDown(root, start, end);
  if (start == end) return tree[root];
  int ans = 0, mid = (start + end) >> 1;
  if (l <= mid) ans += query(l, r, left(root), start, mid);
  if (r > mid) ans += query(l, r, right(root), mid + 1, end);
  dbg();
  return ans;
}

void solve() {
  int m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i)
    cin >> a[i];
  build(1, 1, n);
  while (m--) {
    int op, x, y, k;
    cin >> op >> x >> y;
    switch (op) {
      case 1:
        cin >> k;
        update(x, y, k);
        break;
      case 2:
        cout << query(x, y) << '\n';
        break;
    }
    cerr << '\n';
  }
}

}  // namespace Solution

int main() {
  ios::sync_with_stdio(0);
  cin.tie(nullptr);
  Solution::solve();
  return 0;
}

(祝各位 CSP 2024 rp++)

2024/10/26 08:23
加载中...