Problem p02551 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

int main() {
  size_t N, Q;
  cin >> N >> Q;

  vector<vector<size_t>> s(2, vector<size_t>(N, N - 1));
  vector<size_t> hw(2, N - 1);

  size_t ans = (N - 2) * (N - 2);
  for (size_t q = 0; q < Q; q++) {
    size_t i;
    size_t x;
    cin >> i >> x;
    i--;
    x--;
    size_t j = (i + 1) % 2;

    if (x < hw[i]) {
      for (size_t k = x; k <= hw[i]; k++) {
        s[i][k] = hw[j];
      }
      hw[i] = x;
    }
    size_t y = s[i][x];
    ans -= y - 1;
  }
  cout << ans << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

template <typename T> class SegmentTree {
  std::vector<T> arr;
  const std::size_t size;
  const std::function<T(const T, const T)> operation;
  const T initial_value;

  std::size_t calc_size(const std::size_t N) const {
    std::size_t n = 1;
    while (n < N + 1) {
      n *= 2;
    }
    return n;
  }

  void initialize_array() {
    this->arr = std::vector<T>(2 * this->size - 1, this->initial_value);
  }

  T query(const std::size_t a, const std::size_t b, const std::size_t k,
          const std::size_t l, const std::size_t r) const {
    if (r <= a || b <= l) {
      return this->initial_value;
    }
    if (a <= l && r <= b) {
      return this->arr[k];
    } else {
      return this->operation(this->query(a, b, 2 * k + 1, l, (l + r) / 2),
                             this->query(a, b, 2 * k + 2, (l + r) / 2, r));
    }
  }

public:
  SegmentTree(const std::size_t N,
              const std::function<T(const T, const T)> func, const T init)
      : size(this->calc_size(N)), operation(func), initial_value(init) {
    this->initialize_array();
  }

  void update(const std::size_t idx, const T value) {
    std::size_t modify_idx = idx;
    modify_idx += this->size - 1;
    this->arr[modify_idx] = value;
    while (modify_idx > 0) {
      modify_idx = (modify_idx - 1) / 2;
      this->arr[modify_idx] = this->operation(this->arr[modify_idx * 2 + 1],
                                              this->arr[modify_idx * 2 + 2]);
    }
  }

  T query(const std::size_t idx) const {
    return this->arr[idx + this->size - 1];
  }

  // [idx_a, idx_b)
  T query(const std::size_t idx_a, const std::size_t idx_b) const {
    return this->query(idx_a, idx_b, 0, 0, this->size);
  }

  T operator[](const std::size_t idx) const {
    return this->arr[idx + this->size - 1];
  }
};

int main() {
  size_t N, Q;
  cin >> N >> Q;

  vector<vector<long long>> s(2, vector<long long>(N, N - 1));
  // vector<SegmentTree<long long>> s(
  //     2, SegmentTree<long long>(
  //            N,
  //            [](int a, int b) { return min(a, b); },
  //            INT_MAX));
  // for (size_t i = 1; i < N; i++)
  // {
  //     s[0].update(i, N - 1);
  //     s[1].update(i, N - 1);
  // }

  long long ans = (N - 2) * (N - 2);
  for (size_t q = 0; q < Q; q++) {
    size_t i;
    long long x;
    cin >> i >> x;
    i--;
    x--;
    size_t j = (i + 1) % 2;

    long long y = s[i][x];
    // long long y = s[i].query(x);
    ans -= y - 1;
    for (long long k = 1; k < y; k++) {
      s[j][k] = min(x, s[j][k]);
      // s[j].update(k, x);
    }
    s[i][x] = 0;
    // s[i].update(x, 0);
  }
  cout << ans << endl;
}