Problem p02348 (C++) — buggy submission, verdict: Runtime Error

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

#define DATA_MAX 100000
#define QUERY_MAX 100000
#define UNDEF -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; }

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

    if (Tree[level].size() == 1)
      return;

    for (vector<Node>::size_type i = 0; i < Tree[level].size(); i += 2) {
      tmp.value = MAX_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 s, int t, int n) {
    int iter = s;
    pair<int, int> section(s, t);

    while (iter <= t) {
      iter = UpDate(0, iter, n, section, &Tree[0][iter]);
      iter++;
    }
  }

  int UpDate(int level, int key, int n, pair<int, int> section, Node *before) {
    if (n == UNDEF) {
      if (level == Tree.size() - 1) {
        DownValue(level, key);
        return UNDEF;
      } else {
        UpDate(level + 1, key / 2, n, section, &Tree[level][key]);
        DownValue(level, key);
        return UNDEF;
      }
    }

    if (section.first <= Tree[level][key].low &&
        Tree[level][key].high <= section.second) {
      if (level == Tree.size() - 1) {
        Tree[level][key].value = n;
        return Tree[level][0].high;
      } else {
        Tree[level][key].value = n;
        return UpDate(level + 1, key / 2, n, section, &Tree[level][key]);
      }
    }

    if (level < Tree.size() - 1)
      UpDate(level + 1, key / 2, UNDEF, section, &Tree[level][key]);
    DownValue(level, key, before);

    return before->high;
  }

  void DownValue(int level, int key, Node *before) {
    int tmp = Tree[level][key].value;
    Tree[level][key].value = UNDEF;

    if (tmp != UNDEF) {
      if (before != &Tree[level - 1][2 * key])
        Tree[level - 1][2 * key].value = tmp;
      else if (2 * key + 1 < Tree[level - 1].size())
        Tree[level - 1][2 * key + 1].value = tmp;
    }
  }

  void DownValue(int level, int key) {
    int tmp = Tree[level][key].value;
    Tree[level][key].value = UNDEF;

    if (tmp != UNDEF) {
      Tree[level - 1][2 * key].value = tmp;
      if (2 * key + 1 < Tree[level - 1].size())
        Tree[level - 1][2 * key + 1].value = tmp;
    }
  }

  int Find(int target) {
    int level = (int)Tree.size() - 1;

    if ((Tree[level][0].low <= target && target <= Tree[level][0].high &&
         Tree[level][0].value != UNDEF) ||
        level == 0)
      return Tree[level][0].value;

    if (target <= Tree[level - 1][0].high)
      return Find(level - 1, 0, target);
    else
      return Find(level - 1, 1, target);
  }

  int Find(int level, int key, int target) {
    if (Tree[level][key].low <= target && target <= Tree[level][key].high &&
        Tree[level][key].value != UNDEF)
      return Tree[level][key].value;

    if (target <= Tree[level - 1][2 * key].high ||
        2 * key + 1 > Tree[level - 1].size() - 1)
      return Find(level - 1, 2 * key, target);
    else
      return Find(level - 1, 2 * key + 1, target);
  }

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, s, t, x;

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

        UpDate(s, t, x);
      } else if (com == 1) {
        cin >> x;
        if (!(0 <= x && x < DNum))
          exit(3);

        cout << Find(x) << endl;
      } else
        exit(4);
    }
  }
};

int main() {
  SegTree sg;

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

  return 0;
}


Error: 0

Fixed submission:

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

#define DATA_MAX 100000
#define QUERY_MAX 100000
#define UNDEF -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; }

  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 = MAX_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 s, int t, int n) {
    int iter = s;
    pair<int, int> section(s, t);

    while (iter <= t) {
      iter = UpDate(0, iter, n, section, &Tree[0][iter]);
      iter++;
    }
  }

  int UpDate(int level, int key, int n, pair<int, int> section, Node *before) {
    if (n == UNDEF) {
      if (Tree[level][key].value == UNDEF)
        return UNDEF;
      else if (level == Tree.size() - 1) {
        DownValue(level, key, before);
        return UNDEF;
      } else {
        DownValue(level, key, before);
        return UpDate(level + 1, key / 2, n, section, &Tree[level][key]);
      }
    }

    if (section.first <= Tree[level][key].low &&
        Tree[level][key].high <= section.second) {
      if (level == Tree.size() - 1) {
        Tree[level][key].value = n;
        return Tree[level][0].high;
      } else {
        Tree[level][key].value = n;
        return UpDate(level + 1, key / 2, n, section, &Tree[level][key]);
      }
    }

    DownValue(level, key, before);
    if (level < Tree.size() - 1)
      UpDate(level + 1, key / 2, UNDEF, section, &Tree[level][key]);

    return before->high;
  }

  void DownValue(int level, int key, Node *before) {
    int tmp = Tree[level][key].value;
    Tree[level][key].value = UNDEF;

    if (tmp != UNDEF) {
      if (before != &Tree[level - 1][2 * key])
        Tree[level - 1][2 * key].value = tmp;
      else if (2 * key + 1 < Tree[level - 1].size())
        Tree[level - 1][2 * key + 1].value = tmp;
    }
  }

  int Find(int target) {
    int level = (int)Tree.size() - 1;
    int pivot = (Tree[level][0].high - Tree[level][0].low) / 2;
    Node now = Tree[level][0];

    if (Tree[level][0].low <= target && target <= Tree[level][0].high &&
        Tree[level][0].value != UNDEF)
      return Tree[level][0].value;

    if (target <= pivot)
      return Find(level - 1, 0, target);
    else
      return Find(level - 1, 1, target);
  }

  int Find(int level, int key, int target) {
    Node now = Tree[level][key];
    int pivot = (Tree[level][key].high - Tree[level][key].low) / 2 +
                Tree[level][key].low;

    if (Tree[level][key].low <= target && target <= Tree[level][key].high &&
        Tree[level][key].value != UNDEF)
      return Tree[level][key].value;

    if (target <= pivot)
      return Find(level - 1, 2 * key, target);
    else
      return Find(level - 1, 2 * key + 1, target);
  }

  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, s, t, x;

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

        UpDate(s, t, x);
      } else if (com == 1) {
        cin >> x;
        if (!(0 <= x && x < DNum))
          exit(3);

        cout << Find(x) << endl;
      } else
        exit(4);
    }
  }
};

int main() {
  SegTree sg;

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

  return 0;
}