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

#include <algorithm>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

vector<tuple<long long, long long, string>> vec;
string V;
int N;
long long fact[15];

void dfs(int pos, long long sum, long long prod, string S) {
  if (pos == N) {
    vec.push_back(make_tuple(sum, prod, S));
    return;
  }
  int v = 0;
  if (S.size() >= 1)
    v = (S[S.size() - 1] - '0');

  for (int i = v; i < 10; i++) {
    string SS = S;
    SS += ('0' + i);
    dfs(pos + 1, sum + i, prod * (i + 1), SS);
  }
}

long long anagram(string A1, string A2) {
  int t[10];
  for (int i = 0; i < 10; i++)
    t[i] = 0;
  for (int i = 0; i < A1.size(); i++)
    t[A1[i] - '0']++;

  long long rem = 0;
  for (int i = 0; i < A2.size(); i++) {
    for (int j = 0; j < (A2[i] - '0'); j++) {
      if (t[j] == 0)
        continue;
      t[j]--;
      long long D = fact[N - 1 - i];
      for (int k = 0; k < 10; k++)
        D /= fact[t[k]];
      t[j]++;
      rem += D;
    }
    t[A2[i] - '0']--;
    if (t[A2[i] - '0'] == -1)
      return rem;
  }
  return rem + 1;
}

long long anagram2(string A1) {
  int t[10];
  for (int i = 0; i < 10; i++)
    t[i] = 0;
  for (int i = 0; i < A1.size(); i++)
    t[A1[i] - '0']++;

  long long r = fact[N];
  for (int i = 0; i < 10; i++)
    r /= fact[t[i]];
  return r;
}

int main() {
  fact[0] = 1;
  for (int i = 1; i <= 14; i++)
    fact[i] = 1LL * fact[i - 1] * i;
  cin >> V;
  N = V.size();
  dfs(0, 0, 1, "");
  sort(vec.begin(), vec.end());

  tuple<long long, long long, string> W;
  long long s1 = 0, s2 = 1;
  for (int i = 0; i < V.size(); i++) {
    s1 += (V[i] - '0');
    s2 *= (long long)(V[i] - '0' + 1);
  }
  W = make_tuple(s1, s2, V);
  sort(get<2>(W).begin(), get<2>(W).end());

  long long ans = 0;
  for (int i = 0; i < vec.size(); i++) {
    if (make_pair(get<0>(vec[i]), get<1>(vec[i])) <
        make_pair(get<0>(W), get<1>(W))) {
      string D = get<2>(vec[i]);
      sort(D.begin(), D.end());
      reverse(D.begin(), D.end());
      ans += anagram2(get<2>(vec[i]));
    } else if (make_pair(get<0>(vec[i]), get<1>(vec[i])) ==
               make_pair(get<0>(W), get<1>(W))) {
      ans += anagram(get<2>(vec[i]), V);
    }
  }
  cout << ans - 1 << endl;
  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
long long n, power[15];
vector<pair<long long, long long>> r1[100], r2[100];
void search(int p, int q) {
  for (int i = 0; i < power[p]; i++) {
    string V = to_string(i);
    while (V.size() < p)
      V = '0' + V;
    int s = 0;
    for (int j = 0; j < p; j++)
      s += V[j] - '0';
    long long t = 1;
    for (int j = 0; j < p; j++)
      t *= (long long)(V[j] - '0' + 1);
    if (q == 0)
      r1[s].push_back(make_pair(t, i));
    if (q == 1)
      r2[s].push_back(make_pair(t, i));
  }
}
int main() {
  string S;
  cin >> S;
  n = stoll(S);
  power[0] = 1;
  for (int i = 1; i < 15; i++)
    power[i] = power[i - 1] * 10;
  if (S.size() <= 7) {
    search(S.size(), 0);
    long long D = 0;
    for (int i = 0; i < 100; i++)
      sort(r1[i].begin(), r1[i].end());
    for (int i = 0; i < 100; i++) {
      for (int j = 0; j < r1[i].size(); j++) {
        if (r1[i][j].second == n) {
          cout << D << endl;
        }
        D++;
      }
    }
  } else {
    search(7, 0);
    search(S.size() - 7, 1);
    long long D = 0, P = 0, Q = 1;
    for (int i = 0; i < S.size(); i++) {
      P += S[i] - '0';
      Q *= (S[i] - '0' + 1);
    }
    for (int i = 0; i < 100; i++) {
      sort(r1[i].begin(), r1[i].end());
    }
    for (int i = 0; i < 100; i++) {
      for (int j = 0; j < 100; j++) {
        if (i + j < P)
          D += 1LL * r1[i].size() * r2[j].size();
      }
    }
    for (int i = 0; i <= P; i++) {
      for (int j = 0; j < r2[i].size(); j++) {
        long long c1 = Q / r2[i][j].first;
        long long c2 = power[S.size()];
        long long c3 = n / 10000000LL;
        if ((Q % r2[i][j].first) == 0) {
          if (r2[i][j].second < c3)
            c2 = power[S.size()];
          if (r2[i][j].second == c3)
            c2 = n % 10000000LL - 1LL;
          if (r2[i][j].second > c3)
            c2 = -1;
        }
        int pos1 =
            lower_bound(r1[P - i].begin(), r1[P - i].end(), make_pair(c1, c2)) -
            r1[P - i].begin();
        // cout << r2[i][j].first << ' ' << r2[i][j].second << ' ' << c1 << ' '
        // << c2 << ' ' << pos1 << endl;
        D += pos1;
      }
    }
    cout << D << endl;
  }
  return 0;
}