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

#include "bits/stdc++.h"
#include <random>
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//
struct node;

int ask(const node &l, const node &r);

struct node {
  int id;
  node *l;
  node *r;
  int c_num;
  ld unpower;
  bool pasleft;
  unsigned long long int hash;
  void set_unpower() {
    if (l == nullptr)
      unpower = 0;
    else {
      const auto lhs = l->gethashes();
      const auto rhs = r->gethashes();
      int sum = lhs.size() + rhs.size();
      auto sumhs(lhs);
      sumhs.insert(sumhs.end(), rhs.begin(), rhs.end());
      sort(sumhs.begin(), sumhs.end());
      sumhs.erase(unique(sumhs.begin(), sumhs.end()), sumhs.end());
      int common = sum - sumhs.size();

      unpower = ld(common) / sumhs.size();
    }
  }
  node(const int id_) : id(id_), l(), r(), c_num(1) {
    hash = 1e9 + 7;
    set_unpower();
  }
  node(const int id_, node *l_, node *r_)
      : id(id_), l(l_), r(r_), c_num(1 + l->c_num + r->c_num) {
    unsigned long long int hash0 = l->hash;
    unsigned long long int hash1 = r->hash;
    if (hash0 > hash1)
      swap(hash0, hash1);
    unsigned long long int nhash = hash0 * 101 + hash1 * 103;
    unsigned long long int aa = nhash % (1ll << 31);
    std::mt19937 mt(aa);
    hash = mt();
    hash *= 150094669656737489;
    hash += nhash / (1ll << 31) * 107;
    hash *= static_cast<unsigned long long int>(1e9 + 9);
    set_unpower();
  }
  vector<unsigned long long int> gethashes() {
    vector<unsigned long long int> v(1, hash);
    if (l != NULL) {
      auto lv = l->gethashes();
      auto rv = r->gethashes();
      v.insert(v.end(), lv.begin(), lv.end());
      v.insert(v.end(), rv.begin(), rv.end());
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    return v;
  }
};

node *gettree(const string st, int &a, int &id) {
  if (st[a] == 'x') {
    node *no = new node(id);
    id++;
    a++;
    return no;
  } else {
    int aid = id++;
    assert(st[a] == '(');
    a++;
    node *l = gettree(st, a, id);
    assert(st[a] == ' ');
    a++;
    node *r = gettree(st, a, id);
    node *no = new node(aid, l, r);
    assert(st[a] == ')');
    a++;
    return no;
  }
}

int memo[500][500];
int ask(const node &l, const node &r) {
  if (memo[l.id][r.id] != -2)
    return memo[l.id][r.id];
  else {
    if (l.hash == r.hash)
      return memo[l.id][r.id] = 0;
    else {
      if (abs(l.unpower - r.unpower) < eps) {
        if (l.l == nullptr)
          return memo[l.id][r.id] = 0;
        else {
          node *l0 = l.l;
          node *l1 = l.r;
          node *r0 = r.l;
          node *r1 = r.r;
          if (ask(*l0, *l1) == 1) {
            swap(l0, l1);
          }
          if (ask(*r0, *r1) == 1) {
            swap(r0, r1);
          }
          int stro_num = ask(*l1, *r1);
          if (stro_num != 0) {
            return memo[l.id][r.id] = stro_num;
          } else {
            int weak_num = ask(*l0, *r0);
            return memo[l.id][r.id] = weak_num;
          }
        }
      } else {
        if (l.unpower < r.unpower)
          return memo[l.id][r.id] = 1;
        else
          return memo[l.id][r.id] = -1;
      }
    }
  }
}
void dfs(node &now) {
  if (now.l == nullptr) {

  } else {
    int num = ask(*now.l, *now.r);
    if (num == -1) {
      if (now.pasleft) {
        swap(now.l, now.r);
      }
    } else if (num == 1) {
      if (!now.pasleft) {
        swap(now.l, now.r);
      }
    }
    now.l->pasleft = true;
    now.r->pasleft = false;
    dfs(*now.l);
    dfs(*now.r);
  }
}
void getans(string &ans, node &no) {
  if (no.l == nullptr) {
    ans.push_back('x');
  } else {
    ans.push_back('(');
    getans(ans, *no.l);
    ans.push_back(' ');
    getans(ans, *no.r);
    ans.push_back(')');
    return;
  }
}
int main() {
  while (1) {
    for (int i = 0; i < 500; ++i) {
      for (int j = 0; j < 500; ++j) {
        memo[i][j] = -2;
      }
    }
    string st;
    getline(cin, st);
    if (st == "0")
      break;
    int a = 0;
    int id = 0;
    node *root(gettree(st, a, id));
    root->pasleft = true;
    dfs(*root);
    string ans;
    getans(ans, *root);
    cout << ans << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include "bits/stdc++.h"
#include <random>
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//
struct node;

int ask(const node &l, const node &r);

struct node {
  int id;
  node *l;
  node *r;
  int c_num;
  ld unpower;
  bool pasleft;
  unsigned long long int hash;
  void set_unpower() {
    if (l == nullptr)
      unpower = 0;
    else {
      auto lhs = l->gethashes();
      auto rhs = r->gethashes();
      int sum = lhs.size() + rhs.size();
      lhs.insert(lhs.end(), rhs.begin(), rhs.end());
      sort(lhs.begin(), lhs.end());
      lhs.erase(unique(lhs.begin(), lhs.end()), lhs.end());
      int common = sum - lhs.size();
      unpower = ld(common) / lhs.size();
    }
  }
  node(const int id_) : id(id_), l(), r(), c_num(1) {
    hash = 1e9 + 7;
    set_unpower();
  }
  node(const int id_, node *l_, node *r_)
      : id(id_), l(l_), r(r_), c_num(1 + l->c_num + r->c_num) {
    unsigned long long int hash0 = l->hash;
    unsigned long long int hash1 = r->hash;
    if (hash0 > hash1)
      swap(hash0, hash1);
    unsigned long long int nhash = hash0 * 101 + hash1 * 103;
    std::mt19937 mt(nhash / (1ll << 32));
    hash = mt() + nhash + nhash % (1ll << 32);
    set_unpower();
  }
  vector<long long int> gethashes() {
    vector<long long int> v(1, hash);
    if (l != NULL) {
      auto lv = l->gethashes();
      auto rv = r->gethashes();
      v.insert(v.end(), lv.begin(), lv.end());
      v.insert(v.end(), rv.begin(), rv.end());
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    return v;
  }
};

node *gettree(const string st, int &a, int &id) {
  if (st[a] == 'x') {
    node *no = new node(id);
    id++;
    a++;
    return no;
  } else {
    int aid = id++;
    assert(st[a] == '(');
    a++;
    node *l = gettree(st, a, id);
    assert(st[a] == ' ');
    a++;
    node *r = gettree(st, a, id);
    node *no = new node(aid, l, r);
    assert(st[a] == ')');
    a++;
    return no;
  }
}

int memo[100][100];
int ask(const node &l, const node &r) {
  if (memo[l.id][r.id] != -2)
    return memo[l.id][r.id];
  else {
    if (l.hash == r.hash)
      return memo[l.id][r.id] = 0;
    else {
      if (abs(l.unpower - r.unpower) < eps) {
        if (l.l == nullptr)
          return memo[l.id][r.id] = 0;
        else {
          node *l0 = l.l;
          node *l1 = l.r;
          node *r0 = r.l;
          node *r1 = r.r;
          if (ask(*l0, *l1) == -1) {
            swap(l0, l1);
          }
          if (ask(*r0, *r1) == -1) {
            swap(r0, r1);
          }
          int stro_num = ask(*l1, *r1);
          if (stro_num != 0) {
            return memo[l.id][r.id] = stro_num;
          } else {
            int weak_num = ask(*l0, *l1);
            return memo[l.id][r.id] = weak_num;
          }
        }
      } else {
        if (l.unpower < r.unpower)
          return memo[l.id][r.id] = 1;
        else
          return memo[l.id][r.id] = -1;
      }
    }
  }
}
void dfs(node &now) {
  if (now.l == nullptr) {

  } else {
    int num = ask(*now.l, *now.r);
    if (num == -1) {
      if (now.pasleft) {
        swap(now.l, now.r);
      }
    } else if (num == 1) {
      if (!now.pasleft) {
        swap(now.l, now.r);
      }
    }
    now.l->pasleft = true;
    now.r->pasleft = false;
    dfs(*now.l);
    dfs(*now.r);
  }
}
void getans(string &ans, node &no) {
  if (no.l == nullptr) {
    ans.push_back('x');
  } else {
    ans.push_back('(');
    getans(ans, *no.l);
    ans.push_back(' ');
    getans(ans, *no.r);
    ans.push_back(')');
    return;
  }
}
int main() {
  while (1) {
    for (int i = 0; i < 100; ++i) {
      for (int j = 0; j < 100; ++j) {
        memo[i][j] = -2;
      }
    }
    string st;
    getline(cin, st);
    if (st == "0")
      break;
    int a = 0;
    int id = 0;
    node *root(gettree(st, a, id));
    root->pasleft = true;
    dfs(*root);
    string ans;
    getans(ans, *root);
    cout << ans << endl;
  }

  return 0;
}