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

#include <algorithm>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long
#define endl "\\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'009;

struct fast_io {
  fast_io() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
  };
} fio;

const int NUM_a = 26;

// https://teratail.com/questions/207411?sip=n0070000_019&uid=99331

template <class T, size_t Dim>
class multi_vector : public std::vector<multi_vector<T, Dim - 1>> {
public:
  multi_vector() {}

  template <typename N, typename... Sizes>
  multi_vector(T i, N n, Sizes... sizes)
      : std::vector<multi_vector<T, Dim - 1>>(
            n, multi_vector<T, Dim - 1>(i, sizes...)) {}

  template <typename N, typename... Sizes>
  void resize(T i, N n, Sizes... sizes) {
    std::vector<multi_vector<T, Dim - 1>>::resize(
        n, multi_vector<T, Dim - 1>(i, sizes...));
  }
};

template <class T> class multi_vector<T, 1> : public std::vector<T> {
public:
  multi_vector() {}

  template <typename N> multi_vector(T i, N n) : std::vector<T>(n, i) {}

  template <typename N> void resize(T i, N n) { std::vector<T>::resize(n, i); }
};

constexpr char C = 'a';

struct trie {

  trie *child[NUM_a];
  int val;

  trie() {
    val = 0;
    // for(int _ = 0; _ < NUM_a; _++) child[_] = NULL;
    fill(child, child + NUM_a, (trie *)(0));
  }

  ~trie() {
    /**
     *
     *
     **/
  }

  void add(char *c) {
    if (*c == '\\0')
      return;
    if (this->child[*c - C] == NULL) {
      trie *node = new trie();
      this->child[*c - C] = node;
    }

    if (*(c + 1) == '\\0')
      this->child[*c - C]->val++;

    this->child[*c - C]->add(c + 1);
  }

  int find(char *c) {
    if (*c == '\\0') {
      int con = 0;
      for (int _ = 0; _ < NUM_a; _++) {
        if (this->child[_] != NULL)
          con += this->child[_]->val;
      }
      return this->val - con;
    }

    if (this->child[*c - C] == NULL)
      return 0;
    else
      return this->child[*c - C]->find(c + 1);
  }

  void del(char *c) {
    if (*c == '\\0')
      return;

    if (this->child[*c - C] != NULL) {
      this->child[*c - C]->del(c + 1);
      if (child[*c - C]->val == 1) {
        delete child[*c - C];
        child[*c - C] = NULL;
      } else
        child[*c - C]->val--;
    }
  }

  void print(int depth = 0) {
    for (int _ = 0; _ < NUM_a; _++) {
      if (child[_] != NULL) {
        for (int __ = 0; __ < depth; __++)
          cout << " ";
        cout << (char)(C + _) << " " << child[_]->val << endl;
        this->child[_]->print(depth + 1);
      }
    }
  }

  int count(char *c, vector<bool> &con, int num, int si, bool flag) {
    if (*c == '\\0') {
      return 0;
    }

    int sum = 0;

    if (this->child[*c - C] != NULL)
      sum += this->child[*c - C]->count(c + 1, con, num - 1, si, true);
    else
      count(c + 1, con, num - 1, si, false);

    con[*c - C] = true;

    if (flag) {
      for (int _ = 0; _ < NUM_a; _++) {
        trie *t = this->child[_];

        if (t == NULL)
          continue;

        if (con[_]) {
          sum += t->val;
        }
      }
    }

    return sum;
  }
};

signed main() {
  cout << fixed << setprecision(10);

  int N;
  vector<string> S;
  trie tr;
  int count = 0;

  cin >> N;

  S.resize(N);

  for (int i = 0; i < N; i++) {
    cin >> S[i];
  }

  sort(S.begin(), S.end(), [](string const &lhs, string const &rhs) {
    return lhs.size() < rhs.size();
  });

  for (int i = 0; i < N; i++) {
    vector<bool> con(NUM_a, false);

    reverse(S[i].begin(), S[i].end());

    count += tr.count(&S[i][0], con, S[i].size() - 1, S[i].size(), true);

    tr.add(&S[i][0]);

    S[i].clear();
  }

  cout << count << endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long
#define endl "\\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'009;

struct fast_io {
  fast_io() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
  };
} fio;

const int NUM_a = 26;

// https://teratail.com/questions/207411?sip=n0070000_019&uid=99331

template <class T, size_t Dim>
class multi_vector : public std::vector<multi_vector<T, Dim - 1>> {
public:
  multi_vector() {}

  template <typename N, typename... Sizes>
  multi_vector(T i, N n, Sizes... sizes)
      : std::vector<multi_vector<T, Dim - 1>>(
            n, multi_vector<T, Dim - 1>(i, sizes...)) {}

  template <typename N, typename... Sizes>
  void resize(T i, N n, Sizes... sizes) {
    std::vector<multi_vector<T, Dim - 1>>::resize(
        n, multi_vector<T, Dim - 1>(i, sizes...));
  }
};

template <class T> class multi_vector<T, 1> : public std::vector<T> {
public:
  multi_vector() {}

  template <typename N> multi_vector(T i, N n) : std::vector<T>(n, i) {}

  template <typename N> void resize(T i, N n) { std::vector<T>::resize(n, i); }
};

constexpr char C = 'a';

struct trie {

  trie *child[NUM_a];
  int val;

  trie() {
    val = 0;
    // for(int _ = 0; _ < NUM_a; _++) child[_] = NULL;
    fill(child, child + NUM_a, (trie *)(0));
  }

  ~trie() {
    /**
     *
     *
     **/
  }

  void add(char *c) {
    if (*c == '\\0')
      return;
    if (this->child[*c - C] == NULL) {
      trie *node = new trie();
      this->child[*c - C] = node;
    }

    if (*(c + 1) == '\\0')
      this->child[*c - C]->val++;

    this->child[*c - C]->add(c + 1);
  }

  int find(char *c) {
    if (*c == '\\0') {
      int con = 0;
      for (int _ = 0; _ < NUM_a; _++) {
        if (this->child[_] != NULL)
          con += this->child[_]->val;
      }
      return this->val - con;
    }

    if (this->child[*c - C] == NULL)
      return 0;
    else
      return this->child[*c - C]->find(c + 1);
  }

  void del(char *c) {
    if (*c == '\\0')
      return;

    if (this->child[*c - C] != NULL) {
      this->child[*c - C]->del(c + 1);
      if (child[*c - C]->val == 1) {
        delete child[*c - C];
        child[*c - C] = NULL;
      } else
        child[*c - C]->val--;
    }
  }

  void print(int depth = 0) {
    for (int _ = 0; _ < NUM_a; _++) {
      if (child[_] != NULL) {
        for (int __ = 0; __ < depth; __++)
          cout << " ";
        cout << (char)(C + _) << " " << child[_]->val << endl;
        this->child[_]->print(depth + 1);
      }
    }
  }

  int count(char *c, vector<bool> &con, vector<vector<vector<bool>>> &con2,
            int num, int si) {
    if (*c == '\\0') {
      return 0;
    }

    if (num == 0) {
      return 0;
    }

    int sum = 0;

    for (int _ = 0; _ < NUM_a; _++) {
      trie *t = this->child[_];

      if (t == NULL)
        continue;

      if (num + 1 == si) {
        if (con[_]) {
          sum += t->val;
        }
      }

      for (int __ = 0; __ < NUM_a; __++) {
        if (!con2[num][__][_])
          continue;
        trie *u = t->child[__];

        if (u == NULL)
          continue;

        sum += u->val;
      }
    }

    if (this->child[*c - C] == NULL)
      return sum;
    else
      return this->child[*c - C]->count(c + 1, con, con2, num - 1, si) + sum;
  }
};

/*
1,818,568 KB
1,818 MB
676,000,000 B
676,000 KB
676 MB

*/
signed main() {
  cout << fixed << setprecision(10);

  int N;
  vector<string> S;
  trie tr;
  int count = 0;

  cin >> N;

  S.resize(N);

  for (int i = 0; i < N; i++) {
    cin >> S[i];
  }

  sort(S.begin(), S.end(), [](string const &lhs, string const &rhs) {
    return lhs.size() < rhs.size();
  });

  for (int i = 0; i < N; i++) {
    vector<bool> con(NUM_a, false);
    vector<vector<vector<bool>>> con2(
        S[i].size(), vector<vector<bool>>(NUM_a, vector<bool>(NUM_a, false)));

    for (int j = 0; j < S[i].size(); j++) {

      for (int k = 0; k < NUM_a; k++) {
        if (con[k] == true)
          con2[j][k][S[i][j] - 'a'] = true;
        if (j && con2[j - 1][k][S[i][j] - 'a'])
          con2[j][k][S[i][j] - 'a'] = con2[j - 1][k][S[i][j] - 'a'];
      }

      con[S[i][j] - 'a'] = true;
    }

    reverse(S[i].begin(), S[i].end());

    count += tr.count(&S[i][0], con, con2, S[i].size() - 1, S[i].size());

    tr.add(&S[i][0]);

    S[i].clear();
  }

  cout << count << endl;

  return 0;
}