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

/*
 * 2322.cc: Chinese Classics
 */

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 10000;

/* typedef */

typedef vector<int> vi;
typedef map<string, int> msi;

/* global variables */

bool res[MAX_N], used[MAX_N];
msi types;
int tn, ts[MAX_N], nums[MAX_N];
vi jmps[MAX_N];

/* subroutines */

void read(int k) {
  if (used[k])
    return;
  printf("%d\\n", k + 1);
  used[k] = true;

  if (k > 0 && res[k - 1])
    read(k - 1);
  if (nums[k] > 0) {
    vi &jv = jmps[ts[k]];
    if (jv.size() > nums[k])
      read(jv[nums[k]]);
  }
}

void parse(string &s, string &type, int &num, bool &re) {
  type = "";
  num = 0;
  re = false;
  if (s == "-")
    return;

  int n = s.size();

  if (s[n - 1] == 'v') {
    n--;
    re = true;
  }

  int pos = 0;
  while (pos < n && s[pos] >= 'a' && s[pos] <= 'z')
    type += s[pos++];
  while (pos < n && s[pos] >= '0' && s[pos] <= '9')
    num = num * 10 + (s[pos++] - '0');
}

/* main */

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      break;

    memset(res, false, sizeof(res));
    memset(used, false, sizeof(used));
    memset(ts, -1, sizeof(ts));
    memset(nums, 0, sizeof(nums));
    types.clear();
    tn = 0;

    for (int i = 0; i < n; i++) {
      string s, type;
      cin >> s;
      parse(s, type, nums[i], res[i]);

      if (nums[i] > 0) {
        msi::iterator mit = types.find(type);
        if (mit == types.end() || jmps[mit->second][0] >= 0) {
          ts[i] = types[type] = tn++;
          jmps[ts[i]].assign(nums[i], -1);
          jmps[ts[i]][nums[i] - 1] = i;
        } else {
          ts[i] = mit->second;
          jmps[ts[i]][nums[i] - 1] = i;
        }
      }
    }

    for (int pc = 0; pc < n; pc++)
      if (!res[pc] && nums[pc] <= 1)
        read(pc);
  }

  return 0;
}

Error: TLE

Fixed submission:

/*
 * 2322.cc: Chinese Classics
 */

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 10000;

/* typedef */

typedef vector<int> vi;
typedef map<string, vi> msvi;

/* global variables */

bool res[MAX_N];
string types[MAX_N];
int nums[MAX_N];
msvi jps;

/* subroutines */

void read(int k) {
  for (;;) {
    printf("%d\\n", k + 1);
    if (k > 0 && res[k - 1])
      k--;
    else if (nums[k] > 0) {
      vi &jv = jps[types[k]];
      if (jv.size() > nums[k] + 1)
        k = jv[nums[k] + 1];
      else
        break;
    } else
      break;
  }
}

void parse(string &s, string &type, int &num, bool &re) {
  type = "";
  num = 0;
  re = false;
  int n = s.size();

  if (s[n - 1] == 'v') {
    n--;
    re = true;
  }

  int pos = 0;
  while (pos < n && s[pos] >= 'a' && s[pos] <= 'z')
    type += s[pos++];
  while (pos < n && s[pos] >= '0' && s[pos] <= '9')
    num = num * 10 + (s[pos++] - '0');
}

/* main */

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      break;

    memset(res, false, sizeof(res));
    memset(nums, 0, sizeof(nums));
    jps.clear();

    for (int pc = 0; pc < n; pc++) {
      string s;
      cin >> s;

      if (s == "-")
        read(pc);
      else {
        parse(s, types[pc], nums[pc], res[pc]);
        string &type = types[pc];
        int &num = nums[pc];

        if (num > 0) {
          msvi::iterator mit = jps.find(type);
          if (mit == jps.end()) {
            jps[type] = vi(num + 1, 0);
            jps[type][num] = pc;
          } else
            mit->second[num] = pc;
        }

        if (!res[pc] && num == 1) {
          read(pc);
          jps.erase(type);
        }
      }
    }
  }

  return 0;
}