Cod sursa(job #3293846)

Utilizator anon2718281828Iasmina Matei anon2718281828 Data 12 aprilie 2025 18:46:28
Problema Datorii Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.06 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("datorii.in");
ofstream out("datorii.out");

struct Node {
  Node* parent;
  unique_ptr<Node> left, right;
  int l, r;
  int sum;
};

int getSumFromRange(int a, int b, Node *n) {
  while (n != nullptr) {
    if (n->l == a && n->r == b) {
      return n->sum;
    }

    int m = (n->l + n->r) / 2;
    if (a <= m) {
      n = n->left.get();
    } else {
      n = n->right.get();
    }
  }

  return 0;
}

int main() {
  int n, m;
  in >> n >> m;

  vector<int> s(n + 1);
  for (int i = 1; i <= n; i++) {
    int ai;
    in >> ai;
    s[i] = s[i - 1] + ai;
  }

  unique_ptr<Node> root =
      make_unique<Node>(Node{nullptr, nullptr, nullptr, 1, n, s[n]});
  stack<Node *> stck({root.get()});
  while (!stck.empty()) {
    const auto prev = stck.top();
    stck.pop();

    int m = (prev->l + prev->r) / 2;
    int slm = (m == prev->l) ? s[m] - s[m - 1] : s[m] - s[prev->l - 1];
    int smr = (m == prev->r) ? s[m] - s[m - 1] : s[prev->r] - s[m];
    prev->left =
        make_unique<Node>(Node{prev, nullptr, nullptr, prev->l, m, slm});
    prev->right =
        make_unique<Node>(Node{prev, nullptr, nullptr, m + 1, prev->r, smr});

    if (prev->l != prev->r) {
      stck.emplace(prev->left.get());
      stck.emplace(prev->right.get());
    }
  }

  while (m--) {
    int x, y, z;
    in >> x >> y >> z;

    if (x == 0) {
      Node *n = root.get();
      while (n != nullptr) {
        n->sum -= z;
        if (n->l == n->r)
          break;

        int m = (n->l + n->r) / 2;
        if (y <= m) {
          n = n->left.get();
        } else {
          n = n->right.get();
        }
      }
    } else if (x == 1) {
      int mid = (1 + n) / 2;
      if (y <= mid && z > mid) {
        int sum = getSumFromRange(y, mid, root.get()) +
                  getSumFromRange(mid + 1, z, root.get());
        out << sum << "\n";
      } else {
        int sum = getSumFromRange(y, z, root.get());
        out << sum << "\n";
      }
    }
  }

  return 0;
}