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

#include <algorithm>
#include <array>
#include <climits>
#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 <type_traits>
#include <utility>
#include <vector>

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
using intl32 = std::int_least32_t;
using intl64 = std::int_least64_t;
using uintl32 = std::uint_least32_t;
using uintl64 = std::uint_least64_t;

struct ADD {
  int64 e;
  ADD(int64 x = 0) { e = x; }
  ADD operator*(const ADD &other) { return ADD(e + other.e); }
};
struct MIN {
  int64 e;
  MIN(int64 x = 2147483647) { e = x; }
  MIN operator~() { return *this; }
  MIN operator+(const MIN &other) {
    if (e < other.e)
      return *this;
    return other;
  };
  MIN operator*(const MIN &other) { return other; }
  MIN operator*(const ADD &other) { return MIN(e + other.e); }
};
struct MAX {
  int64 e;
  MAX(int64 x = std::numeric_limits<int64>::min()) { e = x; }
  MAX operator~() { return *this; }
  MAX operator+(const MAX &other) {
    if (e > other.e)
      return *this;
    return other;
  };
  MAX operator*(const MAX &other) { return other; }
  MAX operator*(const ADD &other) { return MAX(e + other.e); }
};
struct SUM {
  int64 e;
  int64 s;
  SUM(int64 x = 0, int64 y = 1) {
    e = x;
    s = y;
  }
  SUM operator~() { return *this; }
  SUM operator+(const SUM &other) { return SUM(e + other.e, s + other.s); };
  SUM operator*(const SUM &other) { return SUM(s * other.e, s); }
  SUM operator*(const ADD &other) { return SUM(e + s * other.e, s); }
};

template <typename Monoid, typename Operand> class lazy_segment_tree {
  struct node {
    Monoid element;
    Operand lazy;
    bool h;
  };
  std::vector<node> tree;
  std::uint_fast32_t size, height;
  void assign(std::uint_fast32_t index, const Operand &data) {
    if (tree[index].h)
      tree[index].lazy = tree[index].lazy * data;
    else {
      tree[index].lazy = data;
      tree[index].h = 1;
    }
  }
  Monoid reflect(std::uint_fast32_t index) {
    if (tree[index].h)
      return tree[index].element * tree[index].lazy;
    return tree[index].element;
  }
  void recalc(std::uint_fast32_t index) {
    tree[index].element = reflect(index << 1) + reflect(index << 1 | 1);
  }
  void push(std::uint_fast32_t index) {
    if (!tree[index].h)
      return;
    assign(index << 1, tree[index].lazy);
    assign(index << 1 | 1, tree[index].lazy);
    tree[index].element = tree[index].element * tree[index].lazy;
    tree[index].h = 0;
  }
  void propagate(std::uint_fast32_t index) {
    std::uint_fast32_t i = height;
    do {
      push(index >> i);
    } while (--i);
  }
  void build(std::uint_fast32_t index) {
    while (index >>= 1)
      recalc(index);
  }

public:
  void update(std::uint_fast32_t begin, std::uint_fast32_t end,
              const Operand &data) {
    begin += size;
    end += size - 1;
    propagate(begin);
    propagate(end);
    for (std::uint_fast32_t left = begin, right = end + 1; left < right;
         left >>= 1, right >>= 1) {
      if (left & 1)
        assign(left++, data);
      if (right & 1)
        assign(--right, data);
    }
    build(begin);
    build(end);
  }
  Monoid range(std::uint_fast32_t begin, std::uint_fast32_t end) {
    begin += size;
    end += size;
    propagate(begin);
    propagate(end - 1);
    Monoid retL, retR;
    for (; begin < end; begin >>= 1, end >>= 1) {
      if (begin & 1)
        retL = retL + reflect(begin++);
      if (end & 1)
        retR = reflect(--end) + retR;
    }
    return retL + retR;
  }
  // trueを返す最小のインデックス
  std::uint_fast32_t binary_search(std::function<bool(Monoid)> bound) {
    if (!bound(reflect(1)))
      return size;
    Monoid ret;
    std::uint_fast32_t i = 1;
    while (i < size) {
      push(i);
      if (!bound(ret + reflect(i <<= 1)))
        ret = ret + reflect(i++);
    }
    return i - size;
  }
  lazy_segment_tree(std::uint_fast32_t length)
      : height(static_cast<std::uint_fast32_t>(0)) {
    --length;
    length |= length >> 1;
    length |= length >> 2;
    length |= length >> 4;
    length |= length >> 8;
    length |= length >> 16;
    if (!length)
      length = 1;
    height = __builtin_popcount(length);
    size = length + 1;
    tree = std::vector<node>(size << 1);
    initialize();
  }
  void update(std::uint_fast32_t index, std::function<Monoid(Monoid)> f) {
    index += size;
    propagate(index);
    if (tree[index].h) {
      tree[index].element = tree[index].element * tree[index].lazy;
      tree[index].h = 0;
    }
    tree[index].element = f(tree[index].element);
    build(index);
  }
  void initialize(void) {
    std::uint_fast32_t const s = size;
    std::uint_fast32_t i = s << 1;
    while (--i >= s) {
      tree[i].element = Monoid();
      tree[i].h = 0;
    }
    do {
      recalc(i);
      tree[i].h = 0;
    } while (--i);
  }
};

int main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  uint32 n, q;
  std::cin >> n >> q;
  lazy_segment_tree<MIN, MIN> T(n);
  uint32 c, s, t;
  std::function<MIN(MIN, uint32)> F = [](const MIN &m, uint32 x) -> MIN {
    return MIN((int64)x);
  };
  do {
    std::cin >> c >> s >> t;
    if (c) {
      std::cout << T.range(s, t + 1).e << "\\n";
    } else {
      T.update(s, std::bind(F, std::placeholders::_1, t));
    }
  } while (--q);
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <climits>
#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 ALL(x) (x).begin(), (x).end()
#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 T> class dynamic_wavelet_matrix {
  class dynamic_FID {
    struct node_t {
      uint32 size, sum, ch[2];
      bool color, bit;
    };
    std::vector<node_t> tree;
    uint32 root, post;
    bool data, balance;
    inline uint32 recalc(uint32 &node) {
      tree[node].size =
          tree[tree[node].ch[0]].size + tree[tree[node].ch[1]].size + 1;
      tree[node].sum = tree[tree[node].ch[0]].sum + tree[tree[node].ch[1]].sum +
                       tree[node].bit;
      return node;
    }
    uint32 rotate(uint32 node, uint32 dir) {
      uint32 t = tree[node].ch[dir ^ 1];
      tree[t].color = tree[node].color;
      tree[node].ch[dir ^ 1] = tree[t].ch[dir];
      tree[node].color = 0;
      tree[t].ch[dir] = recalc(node);
      return recalc(t);
    }
    uint32 subins(uint32 node, uint32 pos) {
      if (!node) {
        balance = 1;
        return post;
      }
      ++tree[node].size;
      tree[node].sum += data;
      if (tree[tree[node].ch[0]].size < pos) {
        tree[node].ch[1] =
            subins(tree[node].ch[1], pos - tree[tree[node].ch[0]].size - 1);
        if (balance)
          return insadj(node, 1);
      } else {
        tree[node].ch[0] = subins(tree[node].ch[0], pos);
        if (balance)
          return insadj(node, 0);
      }
      return node;
    }
    uint32 insadj(uint32 node, bool dir) {
      if (!tree[node].color)
        return node;
      if (tree[tree[tree[node].ch[dir]].ch[0]].color &&
          tree[tree[tree[node].ch[dir]].ch[1]].color) {
        balance = 0;
        return node;
      }
      if (!tree[tree[node].ch[dir ^ 1]].color) {
        tree[tree[node].ch[0]].color = 1;
        tree[tree[node].ch[1]].color = 1;
        tree[node].color = 0;
        return node;
      }
      balance = 0;
      if (!tree[tree[tree[node].ch[dir]].ch[dir ^ 1]].color)
        tree[node].ch[dir] = rotate(tree[node].ch[dir], dir);
      return rotate(node, dir ^ 1);
    }
    uint32 subera(uint32 node, uint32 pos) {
      --tree[node].size;
      if (tree[tree[node].ch[0]].size < pos) {
        tree[node].ch[1] =
            subera(tree[node].ch[1], pos - tree[tree[node].ch[0]].size - 1);
        tree[node].sum -= data;
        if (balance)
          return eraadj(node, 1);
        return node;
      }
      if (tree[tree[node].ch[0]].size > pos) {
        tree[node].ch[0] = subera(tree[node].ch[0], pos);
        tree[node].sum -= data;
        if (balance)
          return eraadj(node, 0);
        return node;
      }
      data = tree[node].bit;
      post = node;
      if (tree[node].ch[0]) {
        if (tree[node].ch[1]) {
          tree[node].ch[1] = subera(tree[node].ch[1], 0);
          std::swap(data, tree[node].bit);
          tree[node].sum -= data;
          if (balance)
            return eraadj(node, 1);
          return node;
        }
        tree[tree[node].ch[0]].color = 1;
        balance = 0;
        return tree[node].ch[0];
      }
      if (tree[node].ch[1]) {
        tree[tree[node].ch[1]].color = 1;
        balance = 0;
        return tree[node].ch[1];
      }
      balance = tree[node].color;
      return 0;
    }
    uint32 eraadj(uint32 node, bool dir) {
      if (tree[tree[tree[node].ch[dir ^ 1]].ch[0]].color &&
          tree[tree[tree[node].ch[dir ^ 1]].ch[1]].color) {
        if (tree[tree[node].ch[dir ^ 1]].color) {
          tree[tree[node].ch[dir ^ 1]].color = 0;
          balance = tree[node].color;
          tree[node].color = 1;
          return node;
        }
        node = rotate(node, dir);
        tree[node].ch[dir] = eraadj(tree[node].ch[dir], dir);
        return node;
      }
      balance = 0;
      if (tree[tree[tree[node].ch[dir ^ 1]].ch[dir ^ 1]].color)
        tree[node].ch[dir ^ 1] = rotate(tree[node].ch[dir ^ 1], dir ^ 1);
      node = rotate(node, dir);
      tree[tree[node].ch[0]].color = 1;
      tree[tree[node].ch[1]].color = 1;
      return node;
    }
    uint32 build(uint32 left, uint32 right, std::vector<char> &a) {
      if (right - left == 1) {
        tree[left] = {1, (uint32)a[left - 1], 0, 0, 1, (bool)a[left - 1]};
        border += !a[left - 1];
        return left;
      }
      if (right - left == 2) {
        tree[left + 1] = {(uint32)2, (uint32)a[left] + (uint32)a[left - 1],
                          left,      0,
                          1,         (bool)a[left]};
        tree[left] = {(uint32)1, (uint32)a[left - 1], 0, 0,
                      0,         (bool)a[left - 1]};
        border += (!a[left]) + (!a[left - 1]);
        return left + 1;
      }
      uint32 mid = (left + right) >> 1;
      border += !a[mid - 1];
      tree[mid] = {0,
                   0,
                   build(left, mid, a),
                   build(mid + 1, right, a),
                   1,
                   (bool)a[mid - 1]};
      return recalc(mid);
    }

  public:
    uint32 border = 0;
    dynamic_FID() {}
    void set(std::vector<char> &a) {
      tree = std::vector<node_t>(a.size() + 1);
      tree[0] = {0, 0, 0, 0, 1, 0};
      root = build(1, tree.size(), a);
      return;
    }
    bool insert(bool bit, uint32 pos) {
      border += !bit;
      data = bit;
      tree[post] = {1, bit, 0, 0, 0, bit};
      root = subins(root, pos);
      tree[root].color = 1;
      return bit;
    }
    bool erase(uint32 pos) {
      root = subera(root, pos);
      border -= !data;
      return data;
    }
    uint32 rank(uint32 pos) {
      uint32 ret = 0, node = root;
      while (node) {
        if (tree[tree[node].ch[0]].size < pos) {
          pos -= tree[tree[node].ch[0]].size + 1;
          ret += tree[tree[node].ch[0]].sum + tree[node].bit;
          node = tree[node].ch[1];
        } else
          node = tree[node].ch[0];
      }
      return ret;
    }
    bool access(uint32 pos) {
      uint32 node = root;
      while (tree[tree[node].ch[0]].size != pos) {
        if (tree[tree[node].ch[0]].size < pos) {
          pos -= tree[tree[node].ch[0]].size + 1;
          node = tree[node].ch[1];
        } else
          node = tree[node].ch[0];
      }
      return tree[node].bit;
    }
    /*
    void show(void) {
    show(root);
    std::cout << "\\n";
    return;
    }
    void show(uint32 node) {
    std::cout << "(";
    if (tree[node].ch[0]) {
    show(tree[node].ch[0]);
    std::cout << "←";
    }
    std::cout << tree[node].bit << " " << (tree[node].color ? "黒" : "赤") << "
    " << tree[node].sum; if (tree[node].ch[1]) { std::cout << "→";
    show(tree[node].ch[1]);
    }
    std::cout << ")";
    return;
    }
    //*/
  };
  uint32 i;
  std::vector<dynamic_FID> tree;
#define bitsize 31
public:
  dynamic_wavelet_matrix(std::vector<T> &a) : tree(bitsize) {
    length = a.size();
    std::vector<std::vector<char>> t(2, std::vector<char>(a.size()));
    std::vector<std::vector<uint32>> c(2, std::vector<uint32>(a.size()));
    i = a.size();
    while (~(--i)) {
      c[bitsize & 1 ^ 1][i] = i;
      t[bitsize & 1 ^ 1][i] = a[i] >> (bitsize - 1) & 1;
    }
    tree[bitsize - 1].set(t[bitsize & 1 ^ 1]);
    i = bitsize;
    uint32 itr, j;
    while (--i) {
      itr = 0;
      for (j = 0; j < a.size(); ++j) {
        if (!t[i & 1][j]) {
          c[i & 1 ^ 1][itr] = c[i & 1][j];
          t[i & 1 ^ 1][itr] = a[c[i & 1][j]] >> (i - 1) & 1;
          ++itr;
        }
      }
      for (j = 0; j < a.size(); ++j) {
        if (t[i & 1][j]) {
          c[i & 1 ^ 1][itr] = c[i & 1][j];
          t[i & 1 ^ 1][itr] = a[c[i & 1][j]] >> (i - 1) & 1;
          ++itr;
        }
      }
      tree[i - 1].set(t[i & 1 ^ 1]);
    }
    return;
  };
  void insert(uint32 position, const T &data) {
    i = bitsize;
    while (~(--i)) {
      if (tree[i].insert(data >> i & 1, position))
        position = tree[i].border + tree[i].rank(position);
      else
        position -= tree[i].rank(position);
    }
    return;
  }
  void erase(uint32 position) {
    i = bitsize;
    while (~(--i)) {
      if (tree[i].erase(position))
        position = tree[i].border + tree[i].rank(position);
      else
        position -= tree[i].rank(position);
    }
    return;
  }
  void update(uint32 position, const T &data) {
    erase(position);
    insert(position, data);
    return;
  }
  T min(uint32 begin, uint32 end) {
    T ret = 0;
    uint32 a, b;
    i = bitsize;
    while (~(--i)) {
      a = tree[i].rank(begin);
      b = tree[i].rank(end);
      if (b + begin == a + end) {
        ret |= (T)1 << i;
        begin = a + tree[i].border;
        end = b + tree[i].border;
      } else {
        begin -= a;
        end -= b;
      }
    }
    return ret;
  }
  T access(uint32 position) {
    T ret = 0;
    i = bitsize;
    while (~(--i)) {
      if (tree[i].access(position)) {
        ret |= (T)1 << i;
        position = tree[i].border + tree[i].rank(position);
      } else
        position -= tree[i].rank(position);
    }
    return ret;
  }
  T rank(uint32 begin, uint32 end, const T &data) {
    i = bitsize;
    while (~(--i)) {
      if (data >> i & 1) {
        begin = tree[i].border + tree[i].rank(begin);
        end = tree[i].border + tree[i].rank(end);
      } else {
        begin -= tree[i].rank(begin);
        end -= tree[i].rank(end);
      }
    }
    return end - begin;
  }
  T rangefreq(uint32 begin, uint32 end, uint32 rank) {
    T ret = 0;
    uint32 a, b;
    i = bitsize;
    while (~(--i)) {
      a = tree[i].rank(begin);
      b = tree[i].rank(end);
      if (b > a + rank) {
        ret |= (T)1 << i;
        begin = a + tree[i].border;
        end = b + tree[i].border;
      } else {
        begin -= a;
        end -= b;
        rank -= b - a;
      }
    }
    return ret;
  }
  //*
  uint32 length;
  void show(void) {
    for (uint32 j = 0; j < length; ++j) {
      std::cout << access(j) << " ";
    }
    std::cout << "\\n";
    return;
  }
  void showbit() {
    for (uint32 j = 5; ~j; --j) {
      for (uint32 k = 0; k < length; ++k) {
        std::cout << tree[j].access(k) << " ";
      }
      std::cout << "bb:" << tree[j].border;
      std::cout << "\\n";
    }
    return;
  }
  //*/
};

int main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  uint32 n, q;
  std::cin >> n;
  std::vector<uint32> a(n, ((uint32)1 << 31) - 1);
  dynamic_wavelet_matrix<uint32> T(a);
  std::cin >> q;
  uint32 c, x, y;
  do {
    std::cin >> c >> x >> y;
    if (c) {
      std::cout << T.min(x, y + 1) << "\\n";
    } else {
      T.update(x, y);
    }
  } while (--q);
  return 0;
}