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

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pint;
typedef pair<ll, ll> pll;

#define debug(x) cout << #x << " = " << (x) << endl;
#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define F first
#define S second

const long double pi = 3.141592653589793;
const int mod = 1e9 + 7;

int n;
ll a, b, c = 0, num;

string n2b(ll num) {
  string ans;
  rep(i, 51) {
    ans.pb('0' + (num & 1));
    num >>= 1;
  }
  reverse(ans.begin(), ans.end());
  return ans;
}

unordered_map<string, ll> dp;

ll solver(int n, ll a, ll b, ll c, bool skip) {
  ll tans = 0;
  if (dp.count(n2b(a) + n2b(b) + n2b(c))) {
    return dp[n2b(a) + n2b(b) + n2b(c)];
  }

  while (n >= 0) {
    bool ba = (a >> n) & 1;
    bool bb = (b >> n) & 1;
    bool bc = (c >> n) & 1;

    num = 4 * ba + 2 * bb + bc;
    if (num == 0 || num == 3 || num == 6) {
      if (ba)
        a ^= (1LL << n);
      if (bb)
        b ^= (1LL << n);
      if (bc)
        c ^= (1LL << n);
      n--;
      if (ba)
        skip = true;
    } else if (num == 2) {
      return -1;
    } else if (num == 1) {
      ll diff = (1LL << n) - b;
      tans += diff;
      a -= diff;
      b += diff;
      if (a < 0 || (a == 0 && skip == false))
        return -1;
    } else if (num == 7) {
      ll diff = a - ((1LL << n) - 1);
      a -= diff;
      if (a < 0 || (a == 0 && skip == false))
        return -1;
      b += diff;
      if (b >> (n + 1))
        return -1;
      tans += diff;
    } else if (num == 4) {
      ll diff = (1LL << n) - b;
      if ((a - diff) & (1LL << n)) {
        b += diff;
        a -= diff;
        tans += diff;
        continue;
      }
      diff = a - ((1LL << n) - 1);
      a -= diff;
      if (a < 0 || (a == 0 && skip == false))
        return -1;
      b += diff;
      if (b >> n)
        return -1;
      tans += diff;
    } else {
      // cout << "HELL" << endl;
      ll ans1 = 111, ans2 = 111;
      {
        if (ba)
          a ^= (1LL << n);
        if (bb)
          b ^= (1LL << n);
        if (bc)
          c ^= (1LL << n);
        n--;
        bool tskip = false;
        if (ba)
          tskip = true;
        ans1 = solver(n, a, b, c, tskip || skip);
        n++;
        if (ba)
          a ^= (1LL << n);
        if (bb)
          b ^= (1LL << n);
        if (bc)
          c ^= (1LL << n);
      }
      if (ans1 != -1)
        ans1 += tans;
      {
        ll diff1 = a - ((1LL << n) - 1);
        ll diff2 = (1LL << n) - b;
        ll diff = max(diff1, diff2);
        a -= diff;
        if (a < 0 || (a == 0 && skip == false))
          ans2 = -1;
        b += diff;
        if (b >> (n + 1))
          ans2 = -1;
        tans += diff;
        if (ans2 != -1)
          ans2 = solver(n, a, b, c, skip);
      }
      if (ans2 != -1)
        ans2 += tans;

      if (ans1 == -1 && ans2 == -1)
        return dp[n2b(a) + n2b(b) + n2b(c)] = -1;
      if (ans1 == -1)
        return dp[n2b(a) + n2b(b) + n2b(c)] = ans2;
      if (ans2 == -1)
        return dp[n2b(a) + n2b(b) + n2b(c)] = ans1;
      return dp[n2b(a) + n2b(b) + n2b(c)] = min(ans1, ans2);
    }
  }

  return dp[n2b(a) + n2b(b) + n2b(c)] = tans;
}

int main() {

  // freopen("input.in","r",stdin);
  // freopen("output.out","w",stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n >> a >> b;
  rep(i, n - 2) {
    cin >> num;
    c ^= num;
  }
  cout << solver(50, a, b, c, false) << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pint;
typedef pair<ll, ll> pll;

#define debug(x) cout << #x << " = " << (x) << endl;
#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define F first
#define S second

const long double pi = 3.141592653589793;
const int mod = 1e9 + 7;

int n;
ll a, b, c = 0, num;

ll solver(int n, ll a, ll b, ll c, bool skip) {
  ll tans = 0;

  while (n >= 0) {
    bool ba = (a >> n) & 1;
    bool bb = (b >> n) & 1;
    bool bc = (c >> n) & 1;

    num = 4 * ba + 2 * bb + bc;
    if (num == 0 || num == 3 || num == 6) {
      if (ba)
        a ^= (1LL << n);
      if (bb)
        b ^= (1LL << n);
      if (bc)
        c ^= (1LL << n);
      n--;
      if (ba)
        skip = true;
    } else if (num == 2) {
      return -1;
    } else if (num == 1) {
      ll diff = (1LL << n) - b;
      tans += diff;
      a -= diff;
      b += diff;
      if (a < 0 || (a == 0 && skip == false))
        return -1;
    } else if (num == 7) {
      ll diff = a - ((1LL << n) - 1);
      a -= diff;
      if (a < 0 || (a == 0 && skip == false))
        return -1;
      b += diff;
      if (b >> (n + 1))
        return -1;
      tans += diff;
    } else if (num == 4) {
      ll diff = (1LL << n) - b;
      if ((a - diff) & (1LL << n)) {
        b += diff;
        a -= diff;
        tans += diff;
        continue;
      }
      diff = a - ((1LL << n) - 1);
      a -= diff;
      if (a < 0 || (a == 0 && skip == false))
        return -1;
      b += diff;
      if (b >> n)
        return -1;
      tans += diff;
    } else {
      // cout << "HELL" << endl;
      ll ans1 = 111, ans2 = 111;
      {
        if (ba)
          a ^= (1LL << n);
        if (bb)
          b ^= (1LL << n);
        if (bc)
          c ^= (1LL << n);
        n--;
        bool tskip = false;
        if (ba)
          tskip = true;
        ans1 = solver(n, a, b, c, tskip || skip);
        n++;
        if (ba)
          a ^= (1LL << n);
        if (bb)
          b ^= (1LL << n);
        if (bc)
          c ^= (1LL << n);
      }
      if (ans1 != -1)
        ans1 += tans;
      {
        ll diff1 = a - ((1LL << n) - 1);
        ll diff2 = (1LL << n) - b;
        ll diff = max(diff1, diff2);
        a -= diff;
        if (a < 0 || (a == 0 && skip == false))
          ans2 = -1;
        b += diff;
        if (b >> (n + 1))
          ans2 = -1;
        tans += diff;
        if (ans2 != -1)
          ans2 = solver(n, a, b, c, skip);
      }
      if (ans2 != -1)
        ans2 += tans;

      if (ans1 == -1 && ans2 == -1)
        return -1;
      if (ans1 == -1)
        return ans2;
      if (ans2 == -1)
        return ans1;
      return min(ans1, ans2);
    }
  }

  return tans;
}

int main() {

  // freopen("input.in","r",stdin);
  // freopen("output.out","w",stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n >> a >> b;
  rep(i, n - 2) {
    cin >> num;
    c ^= num;
  }
  cout << solver(50, a, b, c, false) << endl;

  return 0;
}