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

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
// const int INF = 1e8;
using namespace std;

#define int long long

struct Data {
  char c;
  int n;
  Data(char c, int n) : c(c), n(n) {}
};

void parser(vector<Data> &a) {
  char chr;
  int num;
  while (cin >> chr, chr != '$') {
    cin >> num;
    a.emplace_back(chr, num);
  }
}

vector<Data> a, b, c, ans;

bool canReplace(int idx) {
  rep(i, b.size()) {
    if (a[i + idx].c != b[i].c)
      return false;
    if (i == 0 or i == b.size() - 1) {
      if (a[i + idx].n < b[i].n)
        return false;
    } else {
      if (a[i + idx].n != b[i].n)
        return false;
    }
  }
  return true;
}

signed main() {
  parser(a);
  parser(b);
  parser(c);

  rep(i, static_cast<int>(a.size()) - static_cast<int>(b.size()) + 1) {
    if (canReplace(i)) {
      rep(j, i) ans.emplace_back(a[j]);

      if (b.size() > 1) {
        a[i].n -= b[0].n;
        if (a[i].n > 0)
          ans.emplace_back(a[i]);
      }
      rep(j, c.size()) ans.emplace_back(c[j]);

      a[i + b.size() - 1].n -= b.back().n;
      if (a[i + b.size() - 1].n > 0)
        ans.emplace_back(a[i + b.size() - 1]);
      range(j, i + b.size(), a.size()) ans.emplace_back(a[j]);
      break;
    }
  }

  if (ans.empty())
    ans = a;

  rep(i, ans.size()) {
    if (i + 1 < ans.size() and ans[i + 1].c == ans[i].c) {
      ans[i + 1].n += ans[i].n;
    } else {
      cout << ans[i].c << ' ' << ans[i].n << ' ';
    }
  }
  cout << '$' << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
// const int INF = 1e8;
using namespace std;

#define int long long

struct Data {
  char c;
  int n;
  Data(char c, int n) : c(c), n(n) {}
};

void parser(list<Data> &a) {
  char chr;
  int num;
  while (cin >> chr, chr != '$') {
    cin >> num;
    a.emplace_back(chr, num);
  }
}

list<Data> a, b, c;

bool canReplace(list<Data>::iterator it) {
  int idx = 0;
  // for(auto i : a){ cout << i.c << ' ' << i.n << ' '; } cout << endl;
  for (auto i = it, j = b.begin(); j != b.end(); i++, j++, idx++) {
    if (i->c != j->c)
      return false;
    if (idx == 0 or idx == b.size() - 1) {
      if (i->n < j->n)
        return false;
    } else {
      if (i->n != j->n)
        return false;
    }
  }
  return true;
}

void replaceList(list<Data>::iterator &it) {
  int loop = 1;
  if (b.size() == 1) {
    loop = (it->n) / (b.begin()->n);
    it->n -= loop * b.begin()->n;
    if (it->n == 0)
      it = a.erase(it);
  } else {
    rep(i, b.size()) {
      if (i == 0) {
        it->n -= (*b.begin()).n;
        if (it->n == 0)
          it = a.erase(it);
        else
          it++;
      } else if (i == b.size() - 1) {
        it->n -= (*--b.end()).n;
        if (it->n == 0)
          it = a.erase(it);
      } else {
        it = a.erase(it);
      }
    }
  }
  // show(loop)
  // for(auto i : a){ cout << i.c << ' ' << i.n << ' '; } cout << endl;
  // for(auto i : c){ cout << i.c; } cout << endl;
  while (loop--) {
    for (auto &i : c) {
      a.insert(it, i);
    }
  }
  // for(auto i : a){ cout << i.c << ' ' << i.n << ' '; } cout << endl;
}

bool check() {
  int idx = 0;
  bool f = false;
  for (auto it = a.begin(); idx + b.size() <= a.size(); it++, idx++) {
    if (canReplace(it)) {
      replaceList(it);
      f = true;
    }
  }
  return f;
}

void compress() {
  auto it = a.begin();
  while (it != a.end()) {
    if (it->c == next(it, 1)->c) {
      it->n += next(it, 1)->n;
      a.erase(next(it, 1));
    } else if (it->n == 0) {
      it = a.erase(it);
    } else {
      it++;
    }
  }
}

bool comp() {

  int idx = 0;
  for (auto i = a.begin(), j = b.begin(); i != a.end(); i++, j++, idx++) {
    if (i->c != j->c or i->n != j->n) {
      show(idx) cout << i->c << ' ' << j->c << endl;
      cout << i->n << ' ' << j->n << endl;
      return true;
    }
  }
  return false;
}

signed main() {
  parser(a);
  parser(b);
  parser(c);

  while (true) {
    compress();
    if (check() == false)
      break;
  }

  for (auto i : a) {
    cout << i.c << ' ' << i.n << ' ';
  }
  cout << '$' << endl;
}