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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#pragma comment(linker, "/STACK:400000000")

#define EPS 1e-9
#define INF MOD
#define MOD 1000000007LL
#define fir first
#define foreach(it, X) for (it = X.begin(); it != X.end(); it++)
#define iss istringstream
#define ite iterator
#define ll long long
#define mp make_pair
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < n; i++)
#define pi pair<int, int>
#define pb push_back
#define sec second
#define sh(i) (1LL << i)
#define sst stringstream
#define sz size()
#define vi vector<int>
#define vc vector
#define vl vector<ll>
#define vs vector<string>

string s;
int cur, id;
int memo1[130][130], memo2[130][130];

struct tree {
  tree *l, *r;
  int id, size;
  double sim;
  tree(int x) : id(x) { size = 1, l = NULL, r = NULL; }
};

bool operator!=(const tree &t, const tree &u);

bool operator<(const tree &t, const tree &u) {
  int &res = memo1[t.id][u.id];
  if (res != -1)
    return res;
  if (t.size != u.size)
    return res = t.size < u.size;
  if (t.l == NULL)
    return res = 0;
  if (*t.l != *u.l) {
    return res = *t.l < *u.l;
  }
  if (*t.r != *u.r) {
    return res = *t.r < *u.r;
  }
  return res = 0;
}

bool operator!=(const tree &t, const tree &u) { return t < u || u < t; }

bool diff(const tree &t, const tree &u);

bool stronger(const tree &t, const tree &u) {
  int &res = memo2[t.id][u.id];
  if (res != -1)
    return res;
  if (t.sim != u.sim)
    return res = t.sim < u.sim;
  if (t.l == NULL)
    return res = 0;
  tree *t1, *t2, *u1, *u2;
  if (stronger(*t.l, *t.r))
    t1 = t.l, t2 = t.r;
  else
    t1 = t.r, t2 = t.l;
  if (stronger(*u.l, *u.r))
    u1 = u.l, u2 = u.r;
  else
    u1 = u.r, u2 = u.l;
  if (diff(*t1, *u1)) {
    return res = stronger(*t1, *u1);
  }
  if (diff(*t2, *u2)) {
    return res = stronger(*t2, *u2);
  }
  return res = 0;
}

bool diff(const tree &t, const tree &u) {
  return stronger(t, u) || stronger(u, t);
}
tree *parse() {
  tree *res = new tree(id++);
  if (s[cur] == 'x') {
    cur++;
    return res;
  }
  cur++;
  res->l = parse();
  res->size += res->l->size;
  cur++;
  res->r = parse();
  res->size += res->r->size;
  cur++;
  if (*res->r < *res->l)
    swap(res->l, res->r);
  return res;
}

set<tree> calc(tree *t) {
  set<tree> res;
  res.insert(*t);
  if (t->l == NULL) {
    t->sim = 0;
    return res;
  }
  set<tree> L = calc(t->l), R = calc(t->r);
  set<tree>::ite it;
  int common = 0, total = 0;
  foreach (it, L) {
    total++;
    res.insert(*it);
  }
  foreach (it, R) {
    if (L.count(*it))
      common++;
    else
      total++, res.insert(*it);
  }
  t->sim = 1. * common / total;
  return res;
}

void arrange(tree *t, bool left) {
  if (t->l == NULL)
    return;
  if (left && !stronger(*t->l, *t->r) || !left && stronger(*t->l, *t->r))
    swap(t->l, t->r);
  arrange(t->l, 1);
  arrange(t->r, 0);
}

void show(tree *t) {
  if (t == NULL)
    return;
  if (t->l == NULL) {
    cout << "x";
    return;
  }
  cout << "(";
  show(t->l);
  cout << " ";
  show(t->r);
  cout << ")";
}

int main() {
  while (getline(cin, s) && s[0] != '0') {
    memset(memo1, -1, sizeof(memo1));
    memset(memo2, -1, sizeof(memo2));
    tree *t;
    cur = id = 0;
    t = parse();
    calc(t);
    arrange(t, 1);
    show(t);
    cout << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#pragma comment(linker, "/STACK:400000000")

#define EPS 1e-9
#define INF MOD
#define MOD 1000000007LL
#define fir first
#define foreach(it, X) for (it = X.begin(); it != X.end(); it++)
#define iss istringstream
#define ite iterator
#define ll long long
#define mp make_pair
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < n; i++)
#define pi pair<int, int>
#define pb push_back
#define sec second
#define sh(i) (1LL << i)
#define sst stringstream
#define sz size()
#define vi vector<int>
#define vc vector
#define vl vector<ll>
#define vs vector<string>

string s;
int cur, id;

struct tree {
  tree *l, *r;
  int id, size;
  double sim;
  tree(int x) : id(x) { size = 1, l = NULL, r = NULL; }
};

bool operator!=(const tree &t, const tree &u);

bool operator<(const tree &t, const tree &u) {
  if (t.size != u.size)
    return t.size < u.size;
  if (t.l == NULL)
    return 0;
  if (*t.l != *u.l) {
    return *t.l < *u.l;
  }
  if (*t.r != *u.r) {
    return *t.r < *u.r;
  }
  return 0;
}

bool operator!=(const tree &t, const tree &u) { return t < u || u < t; }

bool diff(const tree &t, const tree &u);

bool stronger(const tree &t, const tree &u) {
  if (t.sim != u.sim)
    return t.sim < u.sim;
  if (t.l == NULL)
    return 0;
  if (diff(*t.l, *u.l)) {
    return stronger(*t.l, *u.l);
  }
  if (diff(*t.r, *u.r)) {
    return stronger(*t.r, *u.r);
  }
  return 0;
}

bool diff(const tree &t, const tree &u) {
  return stronger(t, u) || stronger(u, t);
}
tree *parse() {
  tree *res = new tree(id++);
  if (s[cur] == 'x') {
    cur++;
    return res;
  }
  cur++;
  res->l = parse();
  res->size += res->l->size;
  cur++;
  res->r = parse();
  res->size += res->r->size;
  cur++;
  if (*(res->r) < *(res->l))
    swap(res->l, res->r);
  return res;
}

set<tree> calc(tree *t) {
  set<tree> res;
  res.insert(*t);
  if (t->l == NULL) {
    t->sim = 0;
    return res;
  }
  set<tree> L = calc(t->l), R = calc(t->r);
  set<tree>::ite it;
  int common = 0, total = 0;
  foreach (it, L) {
    total++;
    res.insert(*it);
  }
  foreach (it, R) {
    if (L.count(*it))
      common++;
    else
      total++, res.insert(*it);
  }
  t->sim = 1. * common / total;
  return res;
}

void go(tree *t) {
  if (t == NULL)
    return;
  cout << t->id << ": " << t->sim << endl;
  if (t->l == NULL)
    return;
  go(t->l);
  go(t->r);
}

void arrange(tree *t, bool left) {
  if (t->l == NULL)
    return;
  if (left && stronger(*t->r, *t->l) || !left && stronger(*t->l, *t->r))
    swap(t->l, t->r);
  arrange(t->l, 1);
  arrange(t->r, 0);
}

void show(tree *t) {
  if (t == NULL)
    return;
  if (t->l == NULL) {
    cout << "x";
    return;
  }
  cout << "(";
  show(t->l);
  cout << " ";
  show(t->r);
  cout << ")";
}

int main() {
  while (getline(cin, s) && s[0] != '0') {
    tree *t;
    cur = id = 0;
    t = parse();
    calc(t);
    arrange(t, 1);
    show(t);
    cout << endl;
  }
}