Problem p01842 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>
#include <map>
#include <tuple>
#include <vector>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
int N;
int M;
ll a[50];
ll asum[50];
ll b[50];
ll bsum[50];
inline ll aget(const int l, const int r) {
  return (l <= r ? asum[r] - (l == 0 ? 0 : asum[l - 1]) : 0);
}
inline ll bget(const int l, const int r) {
  return (l <= r ? bsum[r] - (l == 0 ? 0 : bsum[l - 1]) : 0);
}

map<tuple<bool, int, int, int, int, bool>, P> memo;
P dp(const bool Alice, const int l1, const int r1, const int l2, const int r2,
     const bool passed) {
  if (memo.find(make_tuple(Alice, l1, r1, l2, r2, passed)) != memo.end()) {
    return memo[make_tuple(Alice, l1, r1, l2, r2, passed)];
  }
  const bool empty = l1 > r1 and l2 > r2;
  P answer;
  if (Alice) {
    if (r1 == N - 1) {
      if (empty and passed) {
        answer = P{0, 0};
      } else {
        const P next = dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
        const ll sa = aget(l1, r1);
        const ll sb = bget(l2, r2);
        answer = P{next.first + sa, next.second + sb};
      }
    } else {
      const P next1 = (empty and passed)
                          ? P{0, 0}
                          : dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
      const ll sa = aget(l1, r1);
      const ll sb = bget(l2, r2);
      const P ans1 = P{next1.first + sa, next1.second + sb};
      const P ans2 = (a[r1 + 1] == 0)
                         ? dp(not Alice, l1, r1 + 1, r2 + 1, r2, false)
                         : dp(not Alice, l1, r1 + 1, l2, r2, false);
      answer =
          ans1.first - ans1.second > ans2.first - ans2.second ? ans1 : ans2;
    }
  } else {
    if (r2 == M - 1) {
      if (empty and passed) {
        answer = P{0, 0};
      } else {
        const P next = dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
        const ll sa = aget(l1, r1);
        const ll sb = bget(l2, r2);
        answer = P{next.first + sa, next.second + sb};
      }
    } else {
      const P next1 = (empty and passed)
                          ? P{0, 0}
                          : dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
      const ll sa = aget(l1, r1);
      const ll sb = bget(l2, r2);
      const P ans1 = P{next1.first + sa, next1.second + sb};
      const P ans2 = (b[r2 + 1] == 0)
                         ? dp(not Alice, r1 + 1, r1, l2, r2 + 1, false)
                         : dp(not Alice, l1, r1, l2, r2 + 1, empty);
      answer =
          ans1.first - ans1.second < ans2.first - ans2.second ? ans1 : ans2;
    }
  }
  memo[make_tuple(Alice, l1, r1, l2, r2, passed)] = answer;
  return answer;
}

int main() {
  cin >> N >> M;
  for (int i = 0; i < N; i++) {
    cin >> a[i];
    if (a[i] == -1) {
      a[i] = 0;
    }
  }
  asum[0] = a[0];
  for (int i = 1; i < N; i++) {
    asum[i] = asum[i - 1] + a[i];
  }
  for (int i = 0; i < M; i++) {
    cin >> b[i];
    if (b[i] == -1) {
      b[i] = 0;
    }
  }
  bsum[0] = b[0];
  for (int i = 1; i < M; i++) {
    bsum[i] = bsum[i - 1] + b[i];
  }
  const P ans = dp(true, 0, -1, 0, -1, false);
  cout << ans.first - ans.second << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
int N;
int M;
ll a[50];
ll asum[50];
ll b[50];
ll bsum[50];
inline ll aget(const int l, const int r) {
  return (l <= r ? asum[r] - (l == 0 ? 0 : asum[l - 1]) : 0);
}
inline ll bget(const int l, const int r) {
  return (l <= r ? bsum[r] - (l == 0 ? 0 : bsum[l - 1]) : 0);
}

P dp(const bool Alice, const int l1, const int r1, const int l2, const int r2,
     const bool passed) {
  const bool empty = l1 > r1 and l2 > r2;
  if (Alice) {
    if (r1 == N - 1) {
      if (empty and passed) {
        return P{0, 0};
      } else {
        const P next = dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
        const ll sa = aget(l1, r1);
        const ll sb = bget(l2, r2);
        return P{next.first + sa, next.second + sb};
      }
    } else {
      const P next1 = (empty and passed)
                          ? P{0, 0}
                          : dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
      const ll sa = aget(l1, r1);
      const ll sb = bget(l2, r2);
      const P ans1 = P{next1.first + sa, next1.second + sb};
      const P ans2 = (a[r1 + 1] == 0)
                         ? dp(not Alice, l1, r1 + 1, r2 + 1, r2, false)
                         : dp(not Alice, l1, r1 + 1, l2, r2, false);
      return ans1.first - ans1.second > ans2.first - ans2.second ? ans1 : ans2;
    }
  } else {
    if (r2 == M - 1) {
      if (empty and passed) {
        return P{0, 0};
      } else {
        const P next = dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
        const ll sa = aget(l1, r1);
        const ll sb = bget(l2, r2);
        return P{next.first + sa, next.second + sb};
      }
    } else {
      const P next1 = (empty and passed)
                          ? P{0, 0}
                          : dp(not Alice, r1 + 1, r1, r2 + 1, r2, empty);
      const ll sa = aget(l1, r1);
      const ll sb = bget(l2, r2);
      const P ans1 = P{next1.first + sa, next1.second + sb};
      const P ans2 = (b[r2 + 1] == 0)
                         ? dp(not Alice, r1 + 1, r1, l2, r2 + 1, false)
                         : dp(not Alice, l1, r1, l2, r2 + 1, empty);
      return ans1.first - ans1.second < ans2.first - ans2.second ? ans1 : ans2;
    }
  }
}

int main() {
  cin >> N >> M;
  for (int i = 0; i < N; i++) {
    cin >> a[i];
    if (a[i] == -1) {
      a[i] = 0;
    }
  }
  asum[0] = a[0];
  for (int i = 1; i < N; i++) {
    asum[i] = asum[i - 1] + a[i];
  }
  for (int i = 0; i < M; i++) {
    cin >> b[i];
    if (b[i] == -1) {
      b[i] = 0;
    }
  }
  bsum[0] = b[0];
  for (int i = 1; i < M; i++) {
    bsum[i] = bsum[i - 1] + b[i];
  }
  const P ans = dp(true, 0, -1, 0, -1, false);
  cout << ans.first - ans.second << endl;
  return 0;
}