Problem p03856 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 9000000000000000000
#define INF 2000000000

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;
typedef pair<double, int> PDI;

class Union_find {
private:
  vector<int> par;
  vector<int> rank;
  int n;

public:
  Union_find(int a) {
    n = a;
    for (int i = 0; i < n; i++) {
      par.push_back(i);
      rank.push_back(0);
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
};

bool dfs(string s, string to) {
  bool flag = false;
  if (s == to)
    return true;
  if (s != to.substr(0, s.size()))
    return false;

  if (s.size() >= to.size())
    return false;
  if (dfs(s + "dream", to))
    flag = true;
  if (dfs(s + "dreamer", to))
    flag = true;
  if (dfs(s + "erase", to))
    flag = true;
  if (dfs(s + "eraser", to))
    flag = true;

  return flag;
}

int main(void) {
  string s;
  int p = 0;
  string add[4] = {"dream", "dreamer", "erase", "eraser"};
  cin >> s;
  if (dfs("", s))
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 9000000000000000000
#define INF 2000000000

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;
typedef pair<double, int> PDI;

class Union_find {
private:
  vector<int> par;
  vector<int> rank;
  int n;

public:
  Union_find(int a) {
    n = a;
    for (int i = 0; i < n; i++) {
      par.push_back(i);
      rank.push_back(0);
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
};

bool dfs(string s, string to) {
  bool flag = false;
  if (s == to)
    return true;
  if (s != to.substr(0, s.size()))
    return false;

  if (s.size() >= to.size())
    return false;
  if (dfs(s + "dream", to))
    flag = true;
  if (dfs(s + "dreamer", to))
    flag = true;
  if (dfs(s + "erase", to))
    flag = true;
  if (dfs(s + "eraser", to))
    flag = true;

  return flag;
}

int main(void) {
  string s;
  int p = 0;
  string add[4] = {"dream", "dreamer", "erase", "eraser"};
  cin >> s;
  while (p < s.size()) {
    if (s.size() - p < 5) {
      cout << "NO" << endl;
      return 0;
    }
    if (s.substr(p, 5) == add[0]) {
      if (s.substr(p, 7) != add[1]) {
        p += 5;
        continue;
      }
      if (s.substr(p + 5, 5) != add[2]) {
        p += 7;
        continue;
      } else {
        p += 5;
        continue;
      }
    } else if (s.substr(p, 5) == add[2]) {
      if (s.substr(p, 6) != add[3]) {
        p += 5;
        continue;
      }
      if (s.substr(p + 5, 5) != add[2]) {
        p += 6;
        continue;
      } else {
        p += 5;
        continue;
      }
    } else {
      cout << "NO" << endl;
      return 0;
    }
  }
  cout << "YES" << endl;
  return 0;
}