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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll mod = 1000000007;
ll add(ll a, ll b) { return (a + b) % mod; }
ll mul(ll a, ll b) { return (a * b) % mod; }

ll mpow(ll a, ll b) {
  if (b == 0)
    return 1;
  ll res = mpow(mul(a, a), b / 2);
  if (b & 1)
    res = mul(res, a);
  return res;
}

string A, B, C;

ll L[100000];
int solve(string &s) {
  int n = s.size();
  int m = C.size();
  ll res = 0;
  ll num = 0;

  ll B = 1;
  L[n] = 0;
  for (int i = n - 1; i >= 0; i--) {
    L[i] = add(L[i + 1], B * (s[i] - '0'));
    B = mul(B, 10);
  }

  for (int i = 0; i + m <= n; i++) {
    string tmp = s.substr(i, m);
    if (C < tmp) {

      if (C == "0")
        res = add(res, mul(num, mpow(10, n - i - m)));
      else
        res = add(res, mul(num + 1, mpow(10, n - i - m)));

    } else if (C == tmp) {

      if (C == "0") {
        res = add(res, mul(add(num, mod - 1), mpow(10, n - i - m)));
        res = add(res, L[i + m] + 1);
      } else {
        res = add(res, mul(num, mpow(10, n - i - m)));
        res = add(res, L[i + m] + 1);
      }

    } else if (tmp < C) {

      res = add(res, mul(num, mpow(10, n - i - m)));
    }
    num = add(mul(num, 10), s[i] - '0');
  }

  if (C == "0")
    res = add(res, 1);
  return res;
}

int main() {
  cin >> A >> B >> C;

  int ans = mod - solve(A);
  for (int i = 0; i + (int)C.size() <= (int)A.size(); i++) {
    if (A.substr(i, C.size()) == C)
      ans++;
  }
  ans += solve(B);
  ans %= mod;
  cout << ans << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
int mod = 1e9 + 7;
string A, B, C;

int visited[10001][501][2][2];
P mem[10001][501][2][2];

P solveA(int pos, int cnt, int flg, int flg2) {
  if (visited[pos][cnt][flg][flg2])
    return mem[pos][cnt][flg][flg2];

  visited[pos][cnt][flg][flg2] = 1;

  if (cnt == (int)C.size()) {
    P tmp = solveA(pos, 0, flg, flg2);
    if (flg2)
      tmp.first += tmp.second;
    tmp.first %= mod;
    return mem[pos][cnt][flg][flg2] = tmp;
  }

  if (pos == (int)A.size()) {
    return mem[pos][cnt][flg][flg2] = P(0, 1);
  }

  int l = '0';
  int r = '9';
  if (flg == 0)
    r = A[pos];
  int res = 0;
  int res2 = 0;
  for (char ch = l; ch <= r; ch++) {
    int nflg = flg;
    int nflg2 = flg2;
    if (ch != '0')
      nflg2 = 1;
    if (ch < r)
      nflg = 1;

    if (C[cnt] == ch) {
      P p = solveA(pos + 1, cnt + 1, nflg, nflg2);
      res += p.first;
      res %= mod;
      res2 += p.second;
      res2 %= mod;
    } else {
      P p = solveA(pos + 1, 0, nflg, nflg2);
      res += p.first;
      res %= mod;
      res2 += p.second;
      res2 %= mod;
    }
  }
  return mem[pos][cnt][flg][flg2] = P(res, res2);
}

int main() {
  cin >> A >> B >> C;
  P a = solveA(0, 0, 0, 0);
  int ans = mod - a.first;

  for (int i = 0; i + (int)C.size() <= (int)A.size(); i++) {
    if (A.substr(i, C.size()) == C)
      ans++;
  }

  memset(visited, 0, sizeof(visited));
  A = B;
  P b = solveA(0, 0, 0, 0);
  ans = (ans + b.first) % mod;
  //  cout<<a.first<<' '<<b.first<<endl;

  cout << ans << endl;
  return 0;
}