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

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define INF 1000000000
#define MOD 1000000007
#define rep(i, a, b) for (uint32 i = (a); i < (b); ++i)
#define bitget(a, b) (((a) >> (b)) & 1)
#define ALL(x) (x).begin(), (x).end()
#define C(x) std::cout << #x << " : " << x << std::endl
#define scanf scanf_s

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define INF 1000000000
#define MOD 1000000007
#define rep(i, a, b) for (uint32 i = (a); i < (b); ++i)
#define bitget(a, b) (((a) >> (b)) & 1)
#define ALL(x) (x).begin(), (x).end()
#define C(x) std::cout << #x << " : " << x << std::endl
#define scanf scanf_s

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
template <typename Monoid, typename Operand> struct RBnode {
  RBnode *ch[2], *par;
  Monoid value, sum;
  Operand lazy;
  uint32 size, height;
  bool color, reversed; // true=black
};
template <typename Monoid, typename Operand> class RBTrees {
  using Node = RBnode<Monoid, Operand>;
  std::vector<Node> nodes;
  uint32 itr;
  bool balanced;
  Node *backup;

public:
  RBTrees(size_t maxsize) {
    nodes.resize(maxsize + 1);
    itr = 0;
    nodes[0].ch[0] = &nodes[0];
    nodes[0].ch[1] = &nodes[0];
    nodes[0].par = nullptr;
    nodes[0].size = 0;
    nodes[0].height = 1;
    nodes[0].color = 1;
  }
  Node *nil(void) { return &nodes[0]; }
  Node *recalc(Node *node) {
    node->sum = node->value;
    if (node->ch[0] != &nodes[0]) {
      node->sum = node->ch[0]->sum + node->sum;
    }
    if (node->ch[1] != &nodes[0]) {
      node->sum = node->sum + node->ch[1]->sum;
    }
    node->size = node->ch[0]->size + 1 + node->ch[1]->size;
    return node;
  }
  void push(Node *node) {
    node->ch[0]->lazy = node->ch[0]->lazy * node->lazy;
    node->ch[1]->lazy = node->ch[1]->lazy * node->lazy;
    node->value = node->value * node->lazy;
    node->sum = node->sum * node->lazy;
    node->lazy.inactive();
    if (node->reversed) {
      node->ch[0]->reversed ^= 1;
      node->ch[1]->reversed ^= 1;
      std::swap(node->ch[0], node->ch[1]);
      node->sum.reverse();
      node->value.reverse();
      node->reversed = 0;
    }
    return;
  }
  Node *rotate(Node *node, uint32 dir) {
    Node *t = node->ch[dir ^ 1];
    node->ch[dir ^ 1] = t->ch[dir];
    t->ch[dir]->par = node;
    node->height = t->ch[dir]->height;
    t->height = node->height + node->color;
    t->color = node->color;
    node->color = 0;
    t->par = node->par;
    node->par = t;
    t->ch[dir] = recalc(node);
    return recalc(t);
  }
  Node *insert(Node *root, const Monoid &value, uint32 position) {
    nodes[++itr].ch[0] = &nodes[0];
    nodes[itr].ch[1] = &nodes[0];
    nodes[itr].value = value;
    nodes[itr].sum = value;
    nodes[itr].lazy.inactive();
    nodes[itr].size = 1;
    nodes[itr].height = 1;
    nodes[itr].color = 0;
    nodes[itr].reversed = 0;
    backup = nullptr;
    push(root);
    root = _subinsert(root, position);
    if (!root->color) {
      root->height += 1;
      root->color = 1;
    }
    return root;
  }
  Node *_subinsert(Node *node, uint32 pos) {
    if (node == &nodes[0]) {
      balanced = 1;
      nodes[itr].par = backup;
      return &nodes[itr];
    }
    backup = node;
    push(node->ch[0]);
    push(node->ch[1]);
    if (node->ch[0]->size < pos) {
      node->ch[1] = _subinsert(node->ch[1], pos - node->ch[0]->size - 1);
      if (balanced) {
        return _insertadjust(node, 1);
      }
    } else {
      node->ch[0] = _subinsert(node->ch[0], pos);
      if (balanced) {
        return _insertadjust(node, 0);
      }
    }
    return recalc(node);
  }
  Node *_insertadjust(Node *node, uint32 dir) {
    if (!node->color) {
      return recalc(node);
    }
    if (!node->ch[dir ^ 1]->color) {
      if (node->ch[dir]->ch[dir]->color && node->ch[dir]->ch[dir ^ 1]->color) {
        balanced = 0;
        return recalc(node);
      }
      return flip(recalc(node));
    }
    balanced = 0;
    if (node->ch[dir]->ch[dir]->color) {
      if (node->ch[dir]->ch[dir ^ 1]->color) {
        return recalc(node);
      } else {
        node->ch[dir] = rotate(node->ch[dir], dir);
        return rotate(node, dir ^ 1);
      }
    } else {
      if (node->ch[dir]->ch[dir ^ 1]->color) {
        return rotate(node, dir ^ 1);
      } else {
        node->ch[dir] = rotate(node->ch[dir], dir);
        balanced = 1;
        node = rotate(node, dir ^ 1);
        return flip(node);
      }
    }
  }
  Node *flip(Node *node) {
    node->ch[0]->color = 1;
    node->ch[0]->height += 1;
    node->ch[1]->color = 1;
    node->ch[1]->height += 1;
    node->color = 0;
    return node;
  }
  Node *access(Node *root, uint32 position) {
    while (root->ch[0]->size != position) {
      if (position > root->ch[0]->size) {
        position -= root->ch[0]->size + 1;
        root = root->ch[1];
      } else {
        root = root->ch[0];
      }
    }
    return root;
  }
  Node *erase(Node *root, uint32 position) {
    push(root);
    return _suberase(root, position);
  }
  Node *_suberase(Node *node, uint32 position) {
    push(node->ch[0]);
    push(node->ch[1]);
    if (node->ch[0]->size > position) {
      node->ch[0] = _suberase(node->ch[0], position);
      if (balanced) {
        return _eraseadjust(node, 0);
      }
      return recalc(node);
    }
    if (node->ch[0]->size < position) {
      node->ch[1] = _suberase(node->ch[1], position - node->ch[0]->size - 1);
      if (balanced) {
        return _eraseadjust(node, 1);
      }
      return recalc(node);
    }
    if (node->ch[0] != &nodes[0]) {
      if (node->ch[1] != &nodes[0]) {
        node->ch[1] = _suberase(node->ch[1], 0);
        node->value = backup->value;
        if (balanced) {
          return _eraseadjust(node, 1);
        }
        return recalc(node);
      }
      node->ch[0]->par = node->par;
      node->ch[0]->color = 1;
      ++node->ch[0]->height;
      balanced = 0;
      return node->ch[0];
    }
    backup = node;
    if (node->ch[1] != &nodes[0]) {
      node->ch[1]->par = node->par;
      node->ch[1]->color = 1;
      ++node->ch[1]->height;
      balanced = 0;
      return node->ch[1];
    }
    balanced = node->color;
    return &nodes[0];
  }
  Node *_eraseadjust(Node *node, uint32 dir) {
    if (node->ch[dir ^ 1]->ch[0]->color && node->ch[dir ^ 1]->ch[1]->color) {
      if (node->ch[dir ^ 1]->color) {
        node->ch[dir ^ 1]->color = 0;
        --node->ch[dir ^ 1]->height;
        balanced = node->color;
        node->height -= node->color;
        node->color = 1;
        return recalc(node);
      }
      push(node->ch[dir ^ 1]->ch[0]);
      push(node->ch[dir ^ 1]->ch[1]);
      node = rotate(node, dir);
      node->ch[dir] = _eraseadjust(node->ch[dir], dir);
      return node;
    }
    balanced = 0;
    push(node->ch[dir ^ 1]->ch[0]);
    push(node->ch[dir ^ 1]->ch[1]);
    if (node->ch[dir ^ 1]->ch[dir ^ 1]->color) {
      push(node->ch[dir ^ 1]->ch[dir]->ch[0]);
      push(node->ch[dir ^ 1]->ch[dir]->ch[1]);
      node->ch[dir ^ 1] = rotate(node->ch[dir ^ 1], dir ^ 1);
    }
    node = rotate(node, dir);
    ++node->height;
    ++node->ch[0]->height;
    node->ch[0]->color = 1;
    ++node->ch[1]->height;
    node->ch[1]->color = 1;
    return node;
  }
  Monoid range(Node *root, uint32 begin, uint32 end) {
    Node *t = root;
    Monoid ret;
    while (1) {
      push(t);
      if (t->ch[0]->size < begin) {
        begin -= t->ch[0]->size + 1;
        end -= t->ch[0]->size + 1;
        t = t->ch[1];
        continue;
      }
      if (t->ch[0]->size < end) {
        end -= t->ch[0]->size + 1;
        ret = t->value;
        root = t->ch[0];
        t = t->ch[1];
        break;
      }
      t = t->ch[0];
    }
    while (root != &nodes[0]) {
      push(root);
      if (root->ch[0]->size < begin) {
        begin -= root->ch[0]->size + 1;
        root = root->ch[1];
        continue;
      }
      if (root->ch[1] != &nodes[0]) {
        push(root->ch[1]);
        ret = (root->value + root->ch[1]->sum) + ret;
      } else
        ret = root->value + ret;
      root = root->ch[0];
    }
    while (t != &nodes[0]) {
      push(t);
      if (t->ch[0]->size < end) {
        end -= t->ch[0]->size + 1;
        if (t->ch[0] != &nodes[0]) {
          push(t->ch[0]);
          ret = ret + (t->ch[0]->sum + t->value);
        } else
          ret = ret + t->value;
        t = t->ch[1];
        continue;
      }
      t = t->ch[0];
    }
    return ret;
  }
  void update(Node *root, uint32 begin, uint32 end, const Operand &data) {
    Node *t = root;
    push(t);
    while (1) {
      push(t->ch[0]);
      push(t->ch[1]);
      if (t->ch[0]->size < begin) {
        begin -= t->ch[0]->size + 1;
        end -= t->ch[0]->size + 1;
        t = t->ch[1];
        continue;
      }
      if (t->ch[0]->size < end) {
        end -= t->ch[0]->size + 1;
        t->value = t->value * data;
        backup = t;
        break;
      }
      t = t->ch[0];
    }
    root = t->ch[0];
    while (root != &nodes[0]) {
      backup = root;
      if (root->ch[0]->size < begin) {
        begin -= root->ch[0]->size + 1;
        push(root->ch[0]);
        push(root->ch[1]);
        root = root->ch[1];
        continue;
      }
      root->value = root->value * data;
      root->ch[1]->lazy = root->ch[1]->lazy * data;
      push(root->ch[0]);
      push(root->ch[1]);
      root = root->ch[0];
    }
    while (backup != t) {
      backup = recalc(backup)->par;
    }
    root = t->ch[1];
    while (root != &nodes[0]) {
      t = root;
      if (root->ch[0]->size < end) {
        end -= root->ch[0]->size + 1;
        root->value = root->value * data;
        root->ch[0]->lazy = root->ch[0]->lazy * data;
        push(root->ch[0]);
        push(root->ch[1]);
        root = root->ch[1];
        continue;
      }
      push(root->ch[0]);
      push(root->ch[1]);
      root = root->ch[0];
    }
    while (t != nullptr) {
      t = recalc(t)->par;
    }
    return;
  }
  Node *_submerge(Node *left, Node *right, Node *mid) {
    uint32 dir = 1;
    if (left->height < right->height) {
      dir = 0;
      std::swap(left, right);
    }
    if (right == &nodes[0]) {
      uint32 t = itr;
      itr = (mid - &nodes[0]) - 1;
      if (dir) {
        left = insert(left, mid->value, left->size);
      } else {
        left = insert(left, mid->value, 0);
      }
      itr = t;
      return left;
    }
    push(left);
    push(right);
    while (left->height != right->height) {
      push(left->ch[0]);
      push(left->ch[1]);
      left = left->ch[dir];
    }
    mid->ch[dir ^ 1] = left;
    mid->ch[dir] = right;
    recalc(mid)->par = left->par;
    mid->height = left->height;
    mid->color = 0;
    left->par = mid;
    right->par = mid;
    push(left->ch[0]);
    push(left->ch[1]);
    balanced = 1;
    while (mid->par != nullptr) {
      mid->par->ch[dir] = mid;
      mid = mid->par;
      if (balanced) {
        mid = _insertadjust(mid, dir);
      } else {
        recalc(mid);
      }
    }
    if (!mid->color) {
      ++mid->height;
      mid->color = 1;
    }
    return mid;
  }
  Node *merge(Node *left, Node *right) {
    if (right == &nodes[0]) {
      return left;
    }
    right = erase(right, 0);
    return _submerge(left, right, backup);
  }
  void show(Node *node) {
    std::cout << "(";
    if (node->ch[0] != &nodes[0]) {
      show(node->ch[0]);
      std::cout << "←";
    }
    std::cout << node->size << " " << (node->color ? "黒" : "赤") << " "
              << node->height;
    if (node->ch[1] != &nodes[0]) {
      std::cout << "→";
      show(node->ch[1]);
    }
    std::cout << ")";
    return;
  }
  void check(Node *node) {
    if (node->ch[0] != &nodes[0]) {
      if (node->ch[0]->par != node)
        std::cerr << "#\\n";
      check(node->ch[0]);
    }
    if (node->ch[1] != &nodes[0]) {
      if (node->ch[1]->par != node)
        std::cerr << "#\\n";
      check(node->ch[1]);
    }
  }
};
struct SUB {
  int32 e;
  bool a;
  SUB() { inactive(); }
  SUB(int32 x, bool y) {
    e = x;
    a = y;
  }
  void inactive(void) { a = false; }
  SUB operator*(const SUB &other) {
    if (other.a)
      return other;
    return *this;
  }
};
struct MIN {
  int32 e;
  MIN() { set(); }
  MIN(int32 x) { e = x; }
  void set() { e = 2147483647; }
  void reverse(void) {}
  MIN operator+(const MIN &other) {
    if (e < other.e)
      return *this;
    return other;
  };
  MIN operator*(const SUB &other) {
    if (other.a)
      return MIN(other.e);
    return *this;
  }
};
int main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  uint32 n, q;
  std::cin >> n >> q;
  RBTrees<MIN, SUB> T(n);
  RBnode<MIN, SUB> *r = T.nil();
  uint32 c;
  uint32 s, t;
  SUB x;
  x.a = 1;
  //*
  rep(i, 0, n) {
    RBnode<MIN, SUB> *A;
    A = T.insert(T.nil(), MIN(2147483647), 0);
    r = T.merge(A, r);
    // T.show(r);std::cout << "\\n";T.check(r);
  }
  /*/
  std::queue<RBnode<MIN, SUB> *> Q;
  rep(i, 0, n) {
          Q.push(T.insert(r, MIN(2147483647), 0));
  }
  while (Q.size() != 1) {
          RBnode<MIN, SUB> *A, *B;
          A = Q.front();Q.pop();
          B = Q.front();Q.pop();
          Q.push(T.merge(A, B));
  }
  r = Q.front();Q.pop();
  //*/
  // T.show(r);std::cout << "\\n";T.check(r);
  rep(i, 0, q) {
    std::cin >> c >> s >> t;
    if (c == 0) {
      std::cin >> x.e;
      T.update(r, s, t + 1, x);
      // T.show(r);std::cout << "\\n";T.check(r);
    } else {
      std::cout << T.range(r, s, t + 1).e << "\\n";
    }
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define INF 1000000000
#define MOD 1000000007
#define rep(i, a, b) for (uint32 i = (a); i < (b); ++i)
#define bitget(a, b) (((a) >> (b)) & 1)
#define ALL(x) (x).begin(), (x).end()
#define C(x) std::cout << #x << " : " << x << std::endl
#define scanf scanf_s

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define INF 1000000000
#define MOD 1000000007
#define rep(i, a, b) for (uint32 i = (a); i < (b); ++i)
#define bitget(a, b) (((a) >> (b)) & 1)
#define ALL(x) (x).begin(), (x).end()
#define C(x) std::cout << #x << " : " << x << std::endl
#define scanf scanf_s

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
template <typename Monoid, typename Operand> struct RBnode {
  RBnode *ch[2], *par;
  Monoid value, sum;
  Operand lazy;
  uint32 size, height;
  bool color, reversed; // true=black
};
template <typename Monoid, typename Operand> class RBTrees {
  using Node = RBnode<Monoid, Operand>;
  std::vector<Node> nodes;
  uint32 itr;
  bool balanced;
  Node *backup;

public:
  RBTrees(size_t maxsize) {
    nodes.resize(maxsize + 1);
    itr = 0;
    nodes[0].ch[0] = &nodes[0];
    nodes[0].ch[1] = &nodes[0];
    nodes[0].par = nullptr;
    nodes[0].size = 0;
    nodes[0].height = 1;
    nodes[0].color = 1;
  }
  Node *nil(void) { return &nodes[0]; }
  Node *recalc(Node *node) {
    node->sum = node->value;
    if (node->ch[0] != &nodes[0]) {
      node->sum = node->ch[0]->sum + node->sum;
    }
    if (node->ch[1] != &nodes[0]) {
      node->sum = node->sum + node->ch[1]->sum;
    }
    node->size = node->ch[0]->size + 1 + node->ch[1]->size;
    return node;
  }
  void push(Node *node) {
    node->ch[0]->lazy = node->ch[0]->lazy * node->lazy;
    node->ch[1]->lazy = node->ch[1]->lazy * node->lazy;
    node->value = node->value * node->lazy;
    node->sum = node->sum * node->lazy;
    node->lazy.inactive();
    if (node->reversed) {
      node->ch[0]->reversed ^= 1;
      node->ch[1]->reversed ^= 1;
      std::swap(node->ch[0], node->ch[1]);
      node->sum.reverse();
      node->value.reverse();
      node->reversed = 0;
    }
    return;
  }
  Node *rotate(Node *node, uint32 dir) {
    Node *t = node->ch[dir ^ 1];
    node->ch[dir ^ 1] = t->ch[dir];
    t->ch[dir]->par = node;
    node->height = t->ch[dir]->height;
    t->height = node->height + node->color;
    t->color = node->color;
    node->color = 0;
    t->par = node->par;
    node->par = t;
    t->ch[dir] = recalc(node);
    return recalc(t);
  }
  Node *insert(Node *root, const Monoid &value, uint32 position) {
    nodes[++itr].ch[0] = &nodes[0];
    nodes[itr].ch[1] = &nodes[0];
    nodes[itr].value = value;
    nodes[itr].sum = value;
    nodes[itr].lazy.inactive();
    nodes[itr].size = 1;
    nodes[itr].height = 1;
    nodes[itr].color = 0;
    nodes[itr].reversed = 0;
    backup = nullptr;
    push(root);
    root = _subinsert(root, position);
    if (!root->color) {
      root->height += 1;
      root->color = 1;
    }
    return root;
  }
  Node *_subinsert(Node *node, uint32 pos) {
    if (node == &nodes[0]) {
      balanced = 1;
      nodes[itr].par = backup;
      return &nodes[itr];
    }
    backup = node;
    push(node->ch[0]);
    push(node->ch[1]);
    if (node->ch[0]->size < pos) {
      node->ch[1] = _subinsert(node->ch[1], pos - node->ch[0]->size - 1);
      if (balanced) {
        return _insertadjust(node, 1);
      }
    } else {
      node->ch[0] = _subinsert(node->ch[0], pos);
      if (balanced) {
        return _insertadjust(node, 0);
      }
    }
    return recalc(node);
  }
  Node *_insertadjust(Node *node, uint32 dir) {
    if (!node->color) {
      return recalc(node);
    }
    if (!node->ch[dir ^ 1]->color) {
      if (node->ch[dir]->ch[dir]->color && node->ch[dir]->ch[dir ^ 1]->color) {
        balanced = 0;
        return recalc(node);
      }
      return flip(recalc(node));
    }
    balanced = 0;
    if (node->ch[dir]->ch[dir]->color) {
      if (node->ch[dir]->ch[dir ^ 1]->color) {
        return recalc(node);
      } else {
        node->ch[dir] = rotate(node->ch[dir], dir);
        return rotate(node, dir ^ 1);
      }
    } else {
      if (node->ch[dir]->ch[dir ^ 1]->color) {
        return rotate(node, dir ^ 1);
      } else {
        node->ch[dir] = rotate(node->ch[dir], dir);
        balanced = 1;
        node = rotate(node, dir ^ 1);
        return flip(node);
      }
    }
  }
  Node *flip(Node *node) {
    node->ch[0]->color = 1;
    node->ch[0]->height += 1;
    node->ch[1]->color = 1;
    node->ch[1]->height += 1;
    node->color = 0;
    return node;
  }
  Node *access(Node *root, uint32 position) {
    while (root->ch[0]->size != position) {
      if (position > root->ch[0]->size) {
        position -= root->ch[0]->size + 1;
        root = root->ch[1];
      } else {
        root = root->ch[0];
      }
    }
    return root;
  }
  Node *erase(Node *root, uint32 position) {
    push(root);
    return _suberase(root, position);
  }
  Node *_suberase(Node *node, uint32 position) {
    push(node->ch[0]);
    push(node->ch[1]);
    if (node->ch[0]->size > position) {
      node->ch[0] = _suberase(node->ch[0], position);
      if (balanced) {
        return _eraseadjust(node, 0);
      }
      return recalc(node);
    }
    if (node->ch[0]->size < position) {
      node->ch[1] = _suberase(node->ch[1], position - node->ch[0]->size - 1);
      if (balanced) {
        return _eraseadjust(node, 1);
      }
      return recalc(node);
    }
    if (node->ch[0] != &nodes[0]) {
      if (node->ch[1] != &nodes[0]) {
        node->ch[1] = _suberase(node->ch[1], 0);
        node->value = backup->value;
        if (balanced) {
          return _eraseadjust(node, 1);
        }
        return recalc(node);
      }
      node->ch[0]->par = node->par;
      node->ch[0]->color = 1;
      ++node->ch[0]->height;
      balanced = 0;
      return node->ch[0];
    }
    backup = node;
    if (node->ch[1] != &nodes[0]) {
      node->ch[1]->par = node->par;
      node->ch[1]->color = 1;
      ++node->ch[1]->height;
      balanced = 0;
      return node->ch[1];
    }
    balanced = node->color;
    return &nodes[0];
  }
  Node *_eraseadjust(Node *node, uint32 dir) {
    if (node->ch[dir ^ 1]->ch[0]->color && node->ch[dir ^ 1]->ch[1]->color) {
      if (node->ch[dir ^ 1]->color) {
        node->ch[dir ^ 1]->color = 0;
        --node->ch[dir ^ 1]->height;
        balanced = node->color;
        node->height -= node->color;
        node->color = 1;
        return recalc(node);
      }
      push(node->ch[dir ^ 1]->ch[0]);
      push(node->ch[dir ^ 1]->ch[1]);
      node = rotate(node, dir);
      node->ch[dir] = _eraseadjust(node->ch[dir], dir);
      return node;
    }
    balanced = 0;
    push(node->ch[dir ^ 1]->ch[0]);
    push(node->ch[dir ^ 1]->ch[1]);
    if (node->ch[dir ^ 1]->ch[dir ^ 1]->color) {
      push(node->ch[dir ^ 1]->ch[dir]->ch[0]);
      push(node->ch[dir ^ 1]->ch[dir]->ch[1]);
      node->ch[dir ^ 1] = rotate(node->ch[dir ^ 1], dir ^ 1);
    }
    node = rotate(node, dir);
    ++node->height;
    ++node->ch[0]->height;
    node->ch[0]->color = 1;
    ++node->ch[1]->height;
    node->ch[1]->color = 1;
    return node;
  }
  Monoid range(Node *root, uint32 begin, uint32 end) {
    Node *t = root;
    Monoid ret;
    while (1) {
      push(t);
      if (t->ch[0]->size < begin) {
        begin -= t->ch[0]->size + 1;
        end -= t->ch[0]->size + 1;
        t = t->ch[1];
        continue;
      }
      if (t->ch[0]->size < end) {
        end -= t->ch[0]->size + 1;
        ret = t->value;
        root = t->ch[0];
        t = t->ch[1];
        break;
      }
      t = t->ch[0];
    }
    while (root != &nodes[0]) {
      push(root);
      if (root->ch[0]->size < begin) {
        begin -= root->ch[0]->size + 1;
        root = root->ch[1];
        continue;
      }
      if (root->ch[1] != &nodes[0]) {
        push(root->ch[1]);
        ret = (root->value + root->ch[1]->sum) + ret;
      } else
        ret = root->value + ret;
      root = root->ch[0];
    }
    while (t != &nodes[0]) {
      push(t);
      if (t->ch[0]->size < end) {
        end -= t->ch[0]->size + 1;
        if (t->ch[0] != &nodes[0]) {
          push(t->ch[0]);
          ret = ret + (t->ch[0]->sum + t->value);
        } else
          ret = ret + t->value;
        t = t->ch[1];
        continue;
      }
      t = t->ch[0];
    }
    return ret;
  }
  void update(Node *root, uint32 begin, uint32 end, const Operand &data) {
    Node *t = root;
    push(t);
    while (1) {
      push(t->ch[0]);
      push(t->ch[1]);
      if (t->ch[0]->size < begin) {
        begin -= t->ch[0]->size + 1;
        end -= t->ch[0]->size + 1;
        t = t->ch[1];
        continue;
      }
      if (t->ch[0]->size < end) {
        end -= t->ch[0]->size + 1;
        t->value = t->value * data;
        backup = t;
        break;
      }
      t = t->ch[0];
    }
    root = t->ch[0];
    while (root != &nodes[0]) {
      backup = root;
      if (root->ch[0]->size < begin) {
        begin -= root->ch[0]->size + 1;
        push(root->ch[0]);
        push(root->ch[1]);
        root = root->ch[1];
        continue;
      }
      root->value = root->value * data;
      root->ch[1]->lazy = root->ch[1]->lazy * data;
      push(root->ch[0]);
      push(root->ch[1]);
      root = root->ch[0];
    }
    while (backup != t) {
      backup = recalc(backup)->par;
    }
    root = t->ch[1];
    while (root != &nodes[0]) {
      t = root;
      if (root->ch[0]->size < end) {
        end -= root->ch[0]->size + 1;
        root->value = root->value * data;
        root->ch[0]->lazy = root->ch[0]->lazy * data;
        push(root->ch[0]);
        push(root->ch[1]);
        root = root->ch[1];
        continue;
      }
      push(root->ch[0]);
      push(root->ch[1]);
      root = root->ch[0];
    }
    while (t != nullptr) {
      t = recalc(t)->par;
    }
    return;
  }
  Node *_submerge(Node *left, Node *right, Node *mid) {
    uint32 dir = 1;
    if (left->height < right->height) {
      dir = 0;
      std::swap(left, right);
    }
    if (right == &nodes[0]) {
      uint32 t = itr;
      itr = (mid - &nodes[0]) - 1;
      if (dir) {
        left = insert(left, mid->value, left->size);
      } else {
        left = insert(left, mid->value, 0);
      }
      itr = t;
      return left;
    }
    push(left);
    push(right);
    while (left->height != right->height) {
      push(left->ch[0]);
      push(left->ch[1]);
      left = left->ch[dir];
    }
    mid->ch[dir ^ 1] = left;
    mid->ch[dir] = right;
    mid->par = left->par;
    mid->height = left->height;
    mid->color = 0;
    left->par = mid;
    right->par = mid;
    push(left->ch[0]);
    push(left->ch[1]);
    balanced = 1;
    while (mid->par != nullptr) {
      mid->par->ch[dir] = mid;
      mid = mid->par;
      if (balanced) {
        mid = _insertadjust(mid, dir);
      } else {
        recalc(mid);
      }
    }
    if (!mid->color) {
      ++mid->height;
      mid->color = 1;
    }
    return mid;
  }
  Node *merge(Node *left, Node *right) {
    if (right == &nodes[0]) {
      return left;
    }
    right = erase(right, 0);
    return _submerge(left, right, backup);
  }
  void show(Node *node) {
    std::cout << "(";
    if (node->ch[0] != &nodes[0]) {
      show(node->ch[0]);
      std::cout << "←";
    }
    std::cout << node->value.e << " " << node->color << " " << node->height;
    if (node->ch[1] != &nodes[0]) {
      std::cout << "→";
      show(node->ch[1]);
    }
    std::cout << ")";
    return;
  }
  void check(Node *node) {
    if (node->ch[0] != &nodes[0]) {
      if (node->ch[0]->par != node)
        std::cerr << "#\\n";
      check(node->ch[0]);
    }
    if (node->ch[1] != &nodes[0]) {
      if (node->ch[1]->par != node)
        std::cerr << "#\\n";
      check(node->ch[1]);
    }
  }
};
struct SUB {
  int32 e;
  bool a;
  SUB() { inactive(); }
  SUB(int32 x, bool y) {
    e = x;
    a = y;
  }
  void inactive(void) { a = false; }
  SUB operator*(const SUB &other) {
    if (other.a)
      return other;
    return *this;
  }
};
struct MIN {
  int32 e;
  MIN() { set(); }
  MIN(int32 x) { e = x; }
  void set() { e = 2147483647; }
  void reverse(void) {}
  MIN operator+(const MIN &other) {
    if (e < other.e)
      return *this;
    return other;
  };
  MIN operator*(const SUB &other) {
    if (other.a)
      return MIN(other.e);
    return *this;
  }
};
int main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  uint32 n, q;
  std::cin >> n >> q;
  RBTrees<MIN, SUB> T(n);
  RBnode<MIN, SUB> *r = T.nil();
  uint32 c;
  uint32 s, t;
  SUB x;
  x.a = 1;
  /*
  rep(i, 0, n) {
          RBnode<MIN, SUB> *A;
          A = T.insert(T.nil(), MIN(2147483647), 0);
          r = T.merge(A, r);
  }
  /*/
  std::queue<RBnode<MIN, SUB> *> Q;
  rep(i, 0, n) { Q.push(T.insert(r, MIN(2147483647), 0)); }
  while (Q.size() != 1) {
    RBnode<MIN, SUB> *A, *B;
    A = Q.front();
    Q.pop();
    B = Q.front();
    Q.pop();
    Q.push(T.merge(A, B));
  }
  r = Q.front();
  Q.pop();
  //*/
  // T.show(r);std::cout << "\\n";T.check(r);
  rep(i, 0, q) {
    std::cin >> c >> s >> t;
    if (c == 0) {
      std::cin >> x.e;
      T.update(r, s, t + 1, x);
      // T.show(r);std::cout << "\\n";
      // T.check(r);
    } else {
      std::cout << T.range(r, s, t + 1).e << "\\n";
    }
  }
  return 0;
}