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

#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>

#define DATA_MAX 100000
#define QUERY_MAX 100000

#define LEFT 0
#define RIGHT 1

using namespace std;

class SegTree {
  struct Node {
    int value;
    int high;
    int low;
  };

private:
  vector<vector<Node>> Tree;
  const int MAX_VALUE;
  int DNum, QNum;

  int min(int d1, int d2) { return d1 < d2 ? d1 : d2; }

  int min(vector<int> v) {
    int m = v[0];

    for (vector<int>::size_type i = 1; i < v.size(); i++)
      if (m > v[i])
        m = v[i];

    return m;
  }

  void CreateTree(int level) {
    vector<Node> new_layer;
    Node tmp;

    for (vector<Node>::size_type i = 0; i < Tree[level].size(); i += 2) {
      tmp.value = min(Tree[level][i].value, Tree[level][i + 1].value);
      tmp.low = Tree[level][i].low;
      tmp.high = Tree[level][i + 1].high;
      new_layer.push_back(tmp);

      if (i + 2 == Tree[level].size() - 1) {
        tmp = Tree[level][i + 2];
        new_layer.push_back(tmp);
        break;
      }
    }

    Tree.push_back(new_layer);

    if (Tree[level + 1].size() == 1)
      return;
    else
      CreateTree(level + 1);
  }

  void UpDate(int x, int y) {
    int target = x;
    Tree[0][target].value = y;

    for (vector<vector<Node>>::size_type level = 1; level < Tree.size();
         level++) {
      if (target == Tree[level - 1].size() - 1 && Tree[level - 1].size() & 1)
        Tree[level][target / 2].value = Tree[level - 1][target].value;
      else if (target & 1)
        Tree[level][target / 2].value = min(Tree[level - 1][target].value,
                                            Tree[level - 1][target - 1].value);
      else
        Tree[level][target / 2].value = min(Tree[level - 1][target].value,
                                            Tree[level - 1][target + 1].value);

      target /= 2;
    }

    // PrintTree();
  }

  int Find(int x, int y) {
    pair<int, int> section(x, y);
    vector<int> element;
    int iter = x;

    while (iter <= y) {
      iter = Find(element, 0, iter, section, Tree[0][iter]);
      iter++;
    }

    return min(element);
  }

  int Find(vector<int> &element, int level, int key, pair<int, int> section,
           Node before) {
    if (section.first <= Tree[level][key].low &&
        Tree[level][key].high <= section.second) {
      if (level == Tree.size() - 1) {
        element.push_back(Tree[level][0].value);
        return Tree[level][0].high;
      } else
        return Find(element, level + 1, key / 2, section, Tree[level][key]);
    }

    element.push_back(before.value);
    return before.high;
  }

  void PrintTree() {
    static ofstream fout("tree.txt");
    for (int i = (int)Tree.size() - 1; i >= 0; i--) {
      for (vector<Node>::size_type j = 0; j < Tree[i].size(); j++) {
        fout << "(";
        if (Tree[i][j].value == MAX_VALUE)
          fout << "∞";
        else
          fout << Tree[i][j].value;
        fout << ", [" << Tree[i][j].low << ", " << Tree[i][j].high << "])";
      }
      fout << endl;
    }
    fout << endl;
  }

public:
  SegTree() : MAX_VALUE(pow(2, 31) - 1) { Tree.resize(1); }

  void Init() {
    cin >> DNum >> QNum;
    if (!(1 <= DNum && DNum <= DATA_MAX) || !(1 <= QNum && QNum <= QUERY_MAX))
      exit(1);

    Tree[0].resize(DNum);
    for (vector<int>::size_type i = 0; i < Tree[0].size(); i++) {
      Tree[0][i].value = MAX_VALUE;
      Tree[0][i].high = (int)i;
      Tree[0][i].low = (int)i;
    }

    CreateTree(0);
  }

  void ReadQuery() {
    int com, x, y;

    for (int c = 0; c < QNum; c++) {
      cin >> com >> x >> y;
      if (com == 0) {
        if (!(0 <= x && x < DNum) || !(0 <= y && y < MAX_VALUE))
          exit(2);

        UpDate(x, y);
      } else if (com == 1) {
        if (!(0 <= x && x < DNum) || !(0 <= y && y < DNum))
          exit(3);

        if (x == y)
          cout << Tree[0][x].value << endl;
        else if (abs(x - y) == 1)
          cout << min(Tree[0][x].value, Tree[0][y].value) << endl;
        else
          cout << Find(x, y) << endl;
      } else
        exit(4);
    }
  }
};

int main() {
  SegTree sg;

  sg.Init();
  sg.ReadQuery();

  return 0;
}


Error: TLE

Fixed submission:

#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>

#define DATA_MAX 100000
#define QUERY_MAX 100000

#define LEFT 0
#define RIGHT 1

using namespace std;

class SegTree {
  struct Node {
    int value;
    int high;
    int low;
  };

private:
  vector<vector<Node>> Tree;
  const int MAX_VALUE;
  int DNum, QNum;

  int min(int d1, int d2) { return d1 < d2 ? d1 : d2; }

  int min(vector<int> v) {
    int m = v[0];

    for (vector<int>::size_type i = 1; i < v.size(); i++)
      if (m > v[i])
        m = v[i];

    return m;
  }

  void CreateTree(int level) {
    vector<Node> new_layer;
    Node tmp;

    for (vector<Node>::size_type i = 0; i < Tree[level].size(); i += 2) {
      tmp.value = min(Tree[level][i].value, Tree[level][i + 1].value);
      tmp.low = Tree[level][i].low;
      tmp.high = Tree[level][i + 1].high;
      new_layer.push_back(tmp);

      if (i + 2 == Tree[level].size() - 1) {
        tmp = Tree[level][i + 2];
        new_layer.push_back(tmp);
        break;
      }
    }

    Tree.push_back(new_layer);

    if (Tree[level + 1].size() == 1)
      return;
    else
      CreateTree(level + 1);
  }

  void UpDate(int x, int y) {
    int target = x;
    Tree[0][target].value = y;

    for (vector<vector<Node>>::size_type level = 1; level < Tree.size();
         level++) {
      if (target == Tree[level - 1].size() - 1 && Tree[level - 1].size() & 1)
        Tree[level][target / 2].value = Tree[level - 1][target].value;
      else if (target & 1)
        Tree[level][target / 2].value = min(Tree[level - 1][target].value,
                                            Tree[level - 1][target - 1].value);
      else
        Tree[level][target / 2].value = min(Tree[level - 1][target].value,
                                            Tree[level - 1][target + 1].value);

      target /= 2;
    }

    PrintTree();
  }

  int Find(int x, int y) {
    pair<int, int> section(x, y);
    vector<int> element;
    int iter = x;

    while (iter <= y) {
      iter = Find(element, 0, iter, section, Tree[0][iter]);
      iter++;
    }

    return min(element);
  }

  int Find(vector<int> &element, int level, int key, pair<int, int> section,
           Node before) {
    if (section.first <= Tree[level][key].low &&
        Tree[level][key].high <= section.second) {
      if (level == Tree.size() - 1) {
        element.push_back(Tree[level][0].value);
        return Tree[level][0].high;
      } else
        return Find(element, level + 1, key / 2, section, Tree[level][key]);
    }

    element.push_back(before.value);
    return before.high;
  }

  void PrintTree() {
    static ofstream fout("tree.txt");
    for (int i = (int)Tree.size() - 1; i >= 0; i--) {
      for (vector<Node>::size_type j = 0; j < Tree[i].size(); j++) {
        fout << "(";
        if (Tree[i][j].value == MAX_VALUE)
          fout << "∞";
        else
          fout << Tree[i][j].value;
        fout << ", [" << Tree[i][j].low << ", " << Tree[i][j].high << "])";
      }
      fout << endl;
    }
    fout << endl;
  }

public:
  SegTree() : MAX_VALUE(pow(2, 31) - 1) { Tree.resize(1); }

  void Init() {
    cin >> DNum >> QNum;
    if (!(1 <= DNum && DNum <= DATA_MAX) || !(1 <= QNum && QNum <= QUERY_MAX))
      exit(1);

    Tree[0].resize(DNum);
    for (vector<int>::size_type i = 0; i < Tree[0].size(); i++) {
      Tree[0][i].value = MAX_VALUE;
      Tree[0][i].high = (int)i;
      Tree[0][i].low = (int)i;
    }

    CreateTree(0);
  }

  void ReadQuery() {
    int com, x, y;

    for (int c = 0; c < QNum; c++) {
      cin >> com >> x >> y;
      if (com == 0) {
        if (!(0 <= x && x < DNum) || !(0 <= y && y < MAX_VALUE))
          exit(2);

        UpDate(x, y);
      } else if (com == 1) {
        if (!(0 <= x && x < DNum) || !(0 <= y && y < DNum))
          exit(3);

        if (x == y)
          cout << Tree[0][x].value << endl;
        else if (abs(x - y) == 1)
          cout << min(Tree[0][x].value, Tree[0][y].value) << endl;
        else
          cout << Find(x, y) << endl;
      } else
        exit(4);
    }
  }
};

int main() {
  SegTree sg;

  sg.Init();
  sg.ReadQuery();

  return 0;
}