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

#include <algorithm>
#include <array>
#include <cstdio>
#include <functional>
#include <iostream>
#include <list>
#include <numeric>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define _USE_MATH_DEFINES

#include <map>
#include <math.h>

#define SENTINEL 1000000001

#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))

using namespace std;

typedef pair<int, int> pii;

#define NUM 2147483647

int N = 1;
int st[270000];

void init(int first_N) {
  while (N < first_N)
    N *= 2;
}

void update(int update_left, int update_right, int new_value, int node_id,
            int node_left, int node_right) {
  if (update_right < node_left || update_left > node_right)
    return;
  else if (update_left <= node_left && update_right >= node_right) {
    st[node_id] = new_value;
  } else {
    if (st[node_id] >= 0) {
      update(node_left, node_right, st[node_id], 2 * node_id + 1, node_left,
             (node_left + node_right) / 2);
      update(node_left, node_right, st[node_id], 2 * node_id + 2,
             (node_left + node_right) / 2 + 1, node_right);
      st[node_id] = -1;
    }
    update(update_left, update_right, new_value, 2 * node_id + 1, node_left,
           (node_left + node_right) / 2);
    update(update_left, update_right, new_value, 2 * node_id + 2,
           (node_left + node_right) / 2 + 1, node_right);
  }
}

int query(int search_left, int search_right, int node_id, int node_left,
          int node_right) {
  if (search_right < node_left || search_left > node_right) {
    return NUM;
  } else {
    if (st[node_id] != -1)
      return st[node_id];
    else {
      int left = query(search_left, search_right, 2 * node_id + 1, node_left,
                       (node_left + node_right) / 2);
      int right = query(search_left, search_right, 2 * node_id + 2,
                        (node_left + node_right) / 2 + 1, node_right);
      return min(left, right);
    }
  }
}

int main() {
  int first_N, Q;
  scanf("%d %d", &first_N, &Q);

  init(first_N);

  for (int i = 0; i <= 2 * N - 2; i++)
    st[i] = NUM;

  int command, left, right, value;

  for (int i = 0; i < Q; i++) {
    scanf("%d", &command);

    if (command == 0) {
      scanf("%d %d %d", &left, &right, &value);
      update(left, right, value, 0, 0, N - 1);
    } else {
      scanf("%d %d", &left, &right);
      printf("%d\\n", query(left, right, 0, 0, N - 1));
    }
  }
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cstdio>
#include <functional>
#include <iostream>
#include <list>
#include <numeric>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define _USE_MATH_DEFINES

#include <map>
#include <math.h>

#define SENTINEL 1000000001

#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) > (b) ? (a) : (b))

using namespace std;

typedef pair<int, int> pii;

struct SegmentTree {
  int num;
  int l, r;
  int left, right;

  SegmentTree(int l, int r)
      : l(l), r(r), num(2147483647), left(-1), right(-1) {}
};

vector<SegmentTree> st;

int Build(int l, int r) {
  int id = st.size();
  st.push_back(SegmentTree(l, r));
  int m = (l + r) / 2;
  if (l + 1 != r) {
    st[id].left = Build(l, m);
    st[id].right = Build(m, r);
  }
  return id;
}

void Update(int id, int s, int t, int v) {
  if (t <= st[id].l || s >= st[id].r)
    return;
  if (s <= st[id].l && st[id].r <= t) {
    st[id].num = v;
    return;
  }

  if (st[id].num != -1) {
    if (st[id].left != -1) {
      st[st[id].left].num = st[id].num;
    }
    if (st[id].right != -1) {
      st[st[id].right].num = st[id].num;
    }
  }

  int m = (st[id].l + st[id].r) / 2;

  if (m < t) {
    if (st[id].right != -1) {
      Update(st[id].right, s, t, v);
    }
  }
  if (s < m) {
    if (st[id].left != -1) {
      Update(st[id].left, s, t, v);
    }
  }
  st[id].num = -1;
}

int findMin(int id, int s, int t) {
  if (t < st[id].l || s > st[id].r)
    return 2147483647;
  if (st[id].num != -1) {
    return st[id].num;
  } else {
    int mini = 2147483647;

    int m = (st[id].l + st[id].r) / 2;

    if (m < t) {
      if (st[id].right != -1) {
        mini = min(mini, findMin(st[id].right, s, t));
      }
    }
    if (s < m) {
      if (st[id].left != -1) {
        mini = min(mini, findMin(st[id].left, s, t));
      }
    }
    return mini;
  }
}

int main() {
  st.reserve(200010);
  int n, q;
  scanf("%d %d", &n, &q);

  Build(0, n);

  for (int i = 0; i < q; i++) {
    int c, s, t, v;
    scanf("%d", &c);

    switch (c) {
    case 0:
      scanf("%d %d %d", &s, &t, &v);
      Update(0, s, t + 1, v);
      break;
    case 1:
      scanf("%d %d", &s, &t);
      cout << findMin(0, s, t + 1) << endl;
      break;
    }
  }

  return 0;
}