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

#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k]; }
};

int main() {
  int N, Q;
  scanf("%d %d", &N, &Q);
  SegmentTree<int> seg(
      N, [](int a, int b) { return min(a, b); }, INT_MAX);
  while (Q--) {
    int T, X, Y;
    scanf("%d %d %d", &T, &X, &Y);
    if (T == 0)
      seg.update(X, Y);
    else
      printf("%d\\n", seg.query(X, Y + 1));
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

struct Mo_3D {
  vector<int> left, right, index, order;
  vector<bool> v;
  int width;
  int nl, nr, time, ptr;

  Mo_3D(int n)
      : width((int)pow(n, 2.0 / 3.0)), nl(0), nr(0), ptr(0), time(0), v(n) {}

  void insert(int idx, int l, int r) /* [l, r) */
  {
    left.push_back(l);
    right.push_back(r);
    index.push_back(idx);
  }

  void build() {
    order.resize(left.size());
    iota(begin(order), end(order), 0);
    sort(begin(order), end(order), [&](int a, int b) {
      if (left[a] / width != left[b] / width)
        return left[a] < left[b];
      if (right[a] / width != right[b] / width)
        return bool((right[a] < right[b]) ^ (left[a] / width % 2));
      return bool((index[a] < index[b]) ^ (right[a] / width % 2));
    });
  }

  int process() {
    if (ptr == order.size())
      return (-1);
    const auto id = order[ptr];
    while (time < index[id])
      addquery(time++);
    while (time > index[id])
      delquery(--time);
    while (nl > left[id])
      distribute(--nl);
    while (nr < right[id])
      distribute(nr++);
    while (nl < left[id])
      distribute(nl++);
    while (nr > right[id])
      distribute(--nr);
    return (index[order[ptr++]]);
  }

  inline void distribute(int idx) {
    v[idx].flip();
    if (v[idx])
      add(idx);
    else
      del(idx);
  }

  void add(int idx);

  void del(int idx);

  void addquery(int idx);

  void delquery(int idx);
};

int N, Q, A[100000], B[100000], C[100000];
int D[100000], pv[100000];
int ans[100000];
multiset<int> st;

void Mo_3D::add(int idx) { st.emplace(D[idx]); }

void Mo_3D::del(int idx) { st.erase(st.find(D[idx])); }

void Mo_3D::addquery(int idx) {
  if (A[idx] == 1)
    return;
  if (v[B[idx]]) {
    distribute(B[idx]);
    D[B[idx]] = C[idx];
    distribute(B[idx]);
  } else {
    D[B[idx]] = C[idx];
  }
}

void Mo_3D::delquery(int idx) {
  if (A[idx] == 1)
    return;
  if (v[B[idx]]) {
    distribute(B[idx]);
    D[B[idx]] = pv[idx];
    distribute(B[idx]);
  } else {
    D[B[idx]] = pv[idx];
  }
}

int main() {

  scanf("%d %d", &N, &Q);

  Mo_3D mo(N);
  fill_n(D, 100000, 2147483647);
  for (int i = 0; i < Q; i++) {
    scanf("%d %d %d", &A[i], &B[i], &C[i]);
    if (A[i] == 1)
      mo.insert(i, B[i], ++C[i]);
    else
      pv[i] = D[B[i]], D[B[i]] = C[i];
  }

  mo.build();

  fill_n(D, 100000, 2147483647);
  int idx;
  while ((idx = mo.process()) != -1) {
    ans[idx] = *st.begin();
  }

  for (int i = 0; i < Q; i++) {
    if (A[i] == 1)
      printf("%d\\n", ans[i]);
  }
}