Problem p01449 (C++) — buggy submission, verdict: Memory Limit Exceeded


#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;
using msi = map<string, int>;
using mii = map<int, int>;
using pii = pair<int, int>;
using vlai = valarray<int>;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
#define range(i, s, n) for (int i = s; i < n; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define fs first
#define sc second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define INF 1e9
#define EPS 1e-9
struct UnionFind {
  int n;
  set<int> dame;
  vi p;
  vi use;
  UnionFind(int N) : n(N) {
    p.resize(n);
    use.resize(n);
    iota(all(p), 0);
    rep(i, n) {
      int tmp;
      cin >> tmp;
      unite(i, tmp + i);
    }
  }
  void unite(int a, int b) {
    int c = root(a), d = root(b);
    if (c != d)
      p[c] = d;
    else if (a != b)
      dame.insert(root(a));
  }
  int root(int a) { return p[a] = (p[a] == a ? a : root(p[a])); }
  bool same(int a, int b) { return root(a) == root(b); }
  void useable() {
    set<int> tmp;
    for (auto i : dame)
      tmp.insert(root(i));
    dame = tmp;
    rep(i, n) { use[i] = dame.find(root(i)) == dame.end(); }
  }
};
int main() {
  int n;
  cin >> n;
  UnionFind uf(n);
  // rep(i,n)cout<<uf.p[i]<<",";cout<<endl;
  uf.useable();
  // for(auto i :uf.use)cout<<i<<",";cout<<endl;
  int i = 1;
  vvi dp(2, vi(n, 0));
  dp[0][0] = 1;
  while (1) {
    fill(all(dp[i % 2]), 0);
    rep(j, n) {
      if (dp[1 - i % 2][j]) {
        range(d, 1, 7) {
          if (j + d >= n)
            break;
          if (uf.use[j + d]) {
            dp[i % 2][uf.root(j + d)] = 1;
          }
        }
      }
    }
    if (dp[i % 2][n - 1]) {
      cout << i << endl;
      break;
    }
    i++;
  }
  return 0;
}

Error: MLE

Fixed submission:


#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;
using msi = map<string, int>;
using mii = map<int, int>;
using pii = pair<int, int>;
using vlai = valarray<int>;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
#define range(i, s, n) for (int i = s; i < n; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define fs first
#define sc second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define INF 1e9
#define EPS 1e-9
struct UnionFind {
  int n;
  set<int> dame;
  vi p;
  vi use;
  UnionFind(int N) : n(N) {
    p.resize(n);
    use.resize(n);
    iota(all(p), 0);
    rep(i, n) {
      int tmp;
      cin >> tmp;
      unite(i, tmp + i);
    }
  }
  void unite(int a, int b) {
    int c = root(a), d = root(b);
    if (c != d)
      p[c] = d;
    else if (a != b)
      dame.insert(root(a));
  }
  int root(int a) { return p[a] = (p[a] == a ? a : root(p[a])); }
  bool same(int a, int b) { return root(a) == root(b); }
  void useable() {
    set<int> tmp;
    for (auto i : dame)
      tmp.insert(root(i));
    dame = tmp;
    rep(i, n) { use[i] = dame.find(root(i)) == dame.end(); }
  }
};
int main() {
  int n;
  cin >> n;
  UnionFind uf(n);
  // rep(i,n)cout<<uf.p[i]<<",";cout<<endl;
  uf.useable();
  // for(auto i :uf.use)cout<<i<<",";cout<<endl;
  int i = 1;
  vvi dp(1, vi(n, 0));
  dp[0][0] = 1;
  while (1) {
    dp.pb(vi(n, 0));
    rep(j, n) {
      if (dp[i - 1][j]) {
        range(d, 1, 7) {
          if (j + d >= n)
            break;
          if (uf.use[j + d]) {
            dp[i][uf.root(j + d)] = 1;
          }
        }
      }
    }
    if (dp[i][n - 1]) {
      cout << i << endl;
      break;
    }
    i++;
  }
  return 0;
}