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

#include "bits/stdc++.h"
using namespace std;

struct chane {
  int id;
  string st;
};
struct ope {
  bool split;
  int a;
  int b;
};
int check_cut(chane &c) {
  int xnum = (count(c.st.begin(), c.st.end(), 'x'));
  int onum = (count(c.st.begin(), c.st.end(), 'o'));
  if (xnum == onum)
    return -1;
  else {
    assert(xnum < onum);
    int nowx = 0;
    int nowo = 0;
    for (int i = 0; i < c.st.size() - 1; ++i) {
      if (c.st[i] == 'o')
        nowo++;
      else
        nowx++;
      if (nowo == nowx + (onum - xnum) - 1) {
        assert(c.st[0] == 'o' || c.st[i] == 'o');
        return i;
      }
      if (nowx + 1 == nowo) {
        assert(c.st[c.st.size() - 1] == 'o' || c.st[i + 1] == 'o');
        return i;
      }
    }
  }
  return -1;
}
int make_ox(chane &c) {
  if (c.st[0] == 'o' && c.st[1] == 'x') {
    return 1;
  }
  if (c.st[0] == 'x' && c.st[1] == 'o') {
    return 1;
  }
  if (c.st[c.st.size() - 2] == 'o' && c.st[c.st.size() - 1] == 'x') {
    return c.st.size() - 3;
  }
  if (c.st[c.st.size() - 2] == 'x' && c.st[c.st.size() - 1] == 'o') {
    return c.st.size() - 3;
  }
  return -1;
}
int needo(chane &c) {
  int xnum = (count(c.st.begin(), c.st.end(), 'x'));
  int onum = (count(c.st.begin(), c.st.end(), 'o'));
  if (xnum != onum) {
    return -1;
  } else {
    if (c.st[0] == 'x')
      return 0;
    if (c.st[c.st.size() - 1])
      return 1;
    return -1;
  }
}
void solve(const string &ast) {
  vector<ope> opes;
  chane base(chane{0, ast});
  if (ast.size() < 2 * count(ast.begin(), ast.end(), 'x')) {
    cout << -1 << endl;
    return;
  } else if (ast.size() == 2 * count(ast.begin(), ast.end(), 'x')) {
    int num = 0;
    while (base.st.size() > 2) {
      if (make_ox(base) == 1) {
        opes.push_back(ope{true, num, 1});
        num += 2;
        base.st = base.st.substr(2, base.st.size() - 2);
      } else {
        cout << -1 << endl;
        return;
      }
    }
  } else {
    vector<chane> cs;
    cs.push_back(chane{0, ast});
    int nextid = 1;
    while (any_of(cs.begin(), cs.end(),
                  [](const chane &c) { return c.st.size() >= 3; })) {
      bool flag = true;
      while (flag) {
        flag = false;
        {
          vector<chane> newcs;
          for (int i = 0; i < cs.size(); ++i) {
            if (cs[i].st.size() >= 3) {
              const int cut = make_ox(cs[i]);
              if (cut != -1) {
                flag = true;
                opes.push_back(ope{true, cs[i].id, cut});
                newcs.push_back(chane{nextid++, cs[i].st.substr(0, cut + 1)});
                newcs.push_back(
                    chane{nextid++,
                          cs[i].st.substr(cut + 1, cs[i].st.size() - cut - 1)});
              } else {
                newcs.push_back(cs[i]);
              }
            } else if (cs[i].st.size() == 1) {
              newcs.push_back(cs[i]);
            }
          }
          cs = newcs;
        }
        if (!any_of(cs.begin(), cs.end(),
                    [](const chane &c) { return c.st.size() >= 3; }))
          break;
        {
          vector<chane> newcs;
          for (int i = 0; i < cs.size(); ++i) {
            if (cs[i].st.size() == 2) {

            } else {
              newcs.push_back(cs[i]);
            }
          }
          cs = newcs;
        }
      }

      if (!any_of(cs.begin(), cs.end(),
                  [](const chane &c) { return c.st.size() >= 3; }))
        break;
      {
        vector<chane> newcs;
        for (int i = 0; i < cs.size(); ++i) {
          const int cut = check_cut(cs[i]);
          if (cut != -1) {
            opes.push_back(ope{true, cs[i].id, cut});
            newcs.push_back(chane{nextid++, cs[i].st.substr(0, cut + 1)});
            newcs.push_back(chane{
                nextid++, cs[i].st.substr(cut + 1, cs[i].st.size() - cut - 1)});
          } else {
            newcs.push_back(cs[i]);
          }
        }
        cs = newcs;
      }
      if (!any_of(cs.begin(), cs.end(),
                  [](const chane &c) { return c.st.size() >= 3; }))
        break;
      {
        int aid = -1;
        for (int i = 0; i < cs.size(); ++i) {
          if (cs[i].st.size() == 1) {
            assert(cs[i].st[0] == 'o');
            aid = cs[i].id;
            break;
          }
        }

        if (aid != -1) {
          vector<chane> newcs;
          bool used = false;
          for (int i = 0; i < cs.size(); ++i) {
            if (cs[i].id == aid)
              continue;
            int aneed = needo(cs[i]);
            if (aneed == -1 || used) {
              newcs.push_back(cs[i]);
            } else if (aneed == 0) {
              used = true;
              opes.push_back(ope{false, aid, cs[i].id});
              newcs.push_back(chane{nextid++, 'o' + cs[i].st});
            } else {
              used = true;
              opes.push_back(ope{false, cs[i].id, aid});
              newcs.push_back(chane{nextid++, cs[i].st + 'o'});
            }
          }
          if (!used) {
            newcs.push_back(chane{aid, "o"});
          }
          cs = newcs;
        }
      }
    }
  }
  cout << opes.size() << endl;
  for (auto op : opes) {
    if (op.split)
      cout << "split ";
    else
      cout << "join ";
    cout << op.a << " " << op.b << endl;
  }
}

int main() {
  int Q;
  cin >> Q;
  while (Q--) {
    string st;
    cin >> st;
    solve(st);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#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;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt"

struct chane {
  int id;
  string st;
};
struct ope {
  bool split;
  int a;
  int b;
};
int check_cut(chane &c) {
  int xnum = (count(c.st.begin(), c.st.end(), 'x'));
  int onum = (count(c.st.begin(), c.st.end(), 'o'));
  if (xnum == onum)
    return -1;
  else {
    assert(xnum < onum);
    int nowx = 0;
    int nowo = 0;
    for (int i = 0; i < c.st.size() - 1; ++i) {
      if (c.st[i] == 'o')
        nowo++;
      else
        nowx++;
      if (nowo == nowx + (onum - xnum) - 1) {
        assert(c.st[0] == 'o' || c.st[i] == 'o');
        return i;
      }
      /*if (nowx + 1 == nowo) {
              assert(c.st[c.st.size() - 1] == 'o' || c.st[i + 1] == 'o');
              return i;
      }*/
    }
  }
  return -1;
}
int make_ox(chane &c) {
  if (c.st[0] == 'o' && c.st[1] == 'x') {
    return 1;
  }
  if (c.st[0] == 'x' && c.st[1] == 'o') {
    return 1;
  }
  if (c.st[c.st.size() - 2] == 'o' && c.st[c.st.size() - 1] == 'x') {
    return c.st.size() - 3;
  }
  if (c.st[c.st.size() - 2] == 'x' && c.st[c.st.size() - 1] == 'o') {
    return c.st.size() - 3;
  }
  return -1;
}
int needo(chane &c) {
  int xnum = (count(c.st.begin(), c.st.end(), 'x'));
  int onum = (count(c.st.begin(), c.st.end(), 'o'));
  if (xnum != onum) {
    return -1;
  } else {
    if (c.st[0] == 'x')
      return 0;
    if (c.st[c.st.size() - 1])
      return 1;
    return -1;
  }
}
void solve(const string &ast) {
  vector<ope> opes;
  chane base(chane{0, ast});
  if (ast.size() < 2 * count(ast.begin(), ast.end(), 'x')) {
    cout << -1 << endl;
    return;
  } else if (ast.size() == 2 * count(ast.begin(), ast.end(), 'x')) {
    int num = 0;
    while (base.st.size() > 2) {
      if (make_ox(base) == 1) {
        opes.push_back(ope{true, num, 1});
        num += 2;
        base.st = base.st.substr(2, base.st.size() - 2);
      } else {
        cout << -1 << endl;
        return;
      }
    }
  } else {
    vector<chane> cs;
    cs.push_back(chane{0, ast});
    int nextid = 1;
    while (any_of(cs.begin(), cs.end(),
                  [](const chane &c) { return c.st.size() >= 3; })) {
      bool flag = true;
      while (flag) {
        flag = false;
        {
          vector<chane> newcs;
          for (int i = 0; i < cs.size(); ++i) {
            if (cs[i].st.size() >= 3) {
              const int cut = make_ox(cs[i]);
              if (cut != -1) {
                flag = true;
                opes.push_back(ope{true, cs[i].id, cut});
                newcs.push_back(chane{nextid++, cs[i].st.substr(0, cut + 1)});
                newcs.push_back(
                    chane{nextid++,
                          cs[i].st.substr(cut + 1, cs[i].st.size() - cut - 1)});
              } else {
                newcs.push_back(cs[i]);
              }
            } else if (cs[i].st.size() == 1) {
              newcs.push_back(cs[i]);
            }
          }
          cs = newcs;
        }
        if (!any_of(cs.begin(), cs.end(),
                    [](const chane &c) { return c.st.size() >= 3; }))
          break;
        {
          vector<chane> newcs;
          for (int i = 0; i < cs.size(); ++i) {
            if (cs[i].st.size() == 2) {

            } else {
              newcs.push_back(cs[i]);
            }
          }
          cs = newcs;
        }
      }

      if (!any_of(cs.begin(), cs.end(),
                  [](const chane &c) { return c.st.size() >= 3; }))
        break;
      {
        vector<chane> newcs;
        for (int i = 0; i < cs.size(); ++i) {
          const int cut = check_cut(cs[i]);
          if (cut != -1) {
            opes.push_back(ope{true, cs[i].id, cut});
            newcs.push_back(chane{nextid++, cs[i].st.substr(0, cut + 1)});
            newcs.push_back(chane{
                nextid++, cs[i].st.substr(cut + 1, cs[i].st.size() - cut - 1)});
          } else {
            newcs.push_back(cs[i]);
          }
        }
        cs = newcs;
      }
      if (!any_of(cs.begin(), cs.end(),
                  [](const chane &c) { return c.st.size() >= 3; }))
        break;
      {
        int aid = -1;
        for (int i = 0; i < cs.size(); ++i) {
          if (cs[i].st.size() == 1) {
            assert(cs[i].st[0] == 'o');
            aid = cs[i].id;
            break;
          }
        }

        if (aid != -1) {
          vector<chane> newcs;
          bool used = false;
          for (int i = 0; i < cs.size(); ++i) {
            if (cs[i].id == aid)
              continue;
            int aneed = needo(cs[i]);
            if (aneed == -1 || used) {
              newcs.push_back(cs[i]);
            } else if (aneed == 0) {
              used = true;
              opes.push_back(ope{false, aid, cs[i].id});
              newcs.push_back(chane{nextid++, 'o' + cs[i].st});
            } else {
              used = true;
              opes.push_back(ope{false, cs[i].id, aid});
              newcs.push_back(chane{nextid++, cs[i].st + 'o'});
            }
          }
          if (!used) {
            newcs.push_back(chane{aid, "o"});
          }
          cs = newcs;
        }
      }
    }
  }

  cout << opes.size() << endl;
  for (auto op : opes) {
    if (op.split)
      cout << "split ";
    else
      cout << "join ";
    cout << op.a << " " << op.b << endl;
  }
}

int main() {
  int Q;
  cin >> Q;
  while (Q--) {
    string st;
    cin >> st;
    solve(st);
  }
  return 0;
}