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


#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()

using ll = long long;

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }

int main(void) {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  int n;
  std::cin >> n;
  std::vector<ll> A(n);
  rep(i, n) std::cin >> A[i];

  ll S = A[0] + A[1];
  ll X = 0;
  for (int i = 2; i < n; i++)
    X ^= A[i];

  // Find a
  // s.t.   0 < a <= A[0] && a + b == s && a ^ b == x
  // std::cout << "a+b = " << S << std::endl;
  // std::cout << "a^b = " << X << std::endl;
  constexpr int K = 60;
  ll dp[K + 1][3][2];
  rep(i, K + 1) rep(j, 3) rep(m, 2) dp[i][j][m] = -1;
  dp[K][0][1] = 0;

  for (int i = K; i >= 1; i--) {
    int s = (S >> (i - 1)) % 2;
    int x = (X >> (i - 1)) % 2;

    rep(a, 2) rep(b, 2) {
      if ((a ^ b) != x)
        continue;
      rep(j, 3) rep(m, 2) {
        if (dp[i][j][m] == -1)
          continue;
        int k = 2 * j + s - (a + b);
        if (k < 0)
          continue;
        if (k >= 2)
          k = 2;
        int f = (A[0] >> (i - 1)) % 2;
        if (m) {
          if (a == f)
            dp[i - 1][k][m] = std::max(dp[i - 1][k][m], dp[i][j][m] * 2 + a);
          else if (a < f)
            dp[i - 1][k][!m] = std::max(dp[i - 1][k][!m], dp[i][j][m] * 2 + a);
        } else
          dp[i - 1][k][m] = std::max(dp[i - 1][k][m], dp[i][j][m] * 2 + a);
      }
    }
  }

  ll v = std::max(dp[0][0][0], dp[0][0][1]);
  if (v == -1 || v == 0)
    std::cout << -1 << std::endl;
  else
    std::cout << A[0] - v << std::endl;
  return 0;
}


Error: TLE

Fixed submission:


#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()

using ll = long long;

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }

int main(void) {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  int n;
  std::cin >> n;
  std::vector<ll> A(n);
  rep(i, n) std::cin >> A[i];

  ll S = A[0] + A[1];
  ll X = 0;
  for (int i = 2; i < n; i++)
    X ^= A[i];

  // Find a
  // s.t.   0 < a <= A[0] && a + b == s && a ^ b == x
  // std::cout << "a+b = " << S << std::endl;
  // std::cout << "a^b = " << X << std::endl;
  constexpr int K = 60;
  std::set<ll> dp[K + 1][3];
  // rep(i,K+1) rep(j,3) dp[i][j] = -1;
  dp[K][0].insert(0);

  for (int i = K; i >= 1; i--) {
    int s = (S >> (i - 1)) % 2;
    int x = (X >> (i - 1)) % 2;

    rep(a, 2) rep(b, 2) {
      if ((a ^ b) != x)
        continue;
      rep(j, 3) {
        if (dp[i][j].size() == 0)
          continue;
        int k = 2 * j + s - (a + b);
        if (k < 0)
          continue;
        if (k >= 2)
          k = 2;
        for (auto &&v : dp[i][j]) {
          if (v * 2 + a <= (A[0] >> (i - 1))) {
            dp[i - 1][k].insert(v * 2 + a);
            // std::cout << "Loop : " << i << " " << j << " a = " << a << " b =
            // " << b << " : dp[" << i-1 << "][" << k << "] = " << dp[i-1][k] <<
            // " <= " << (A[0]>>(i-1)) << std::endl;
          }
        }
      }
    }
  }

  if (dp[0][0].size() == 0 || *dp[0][0].rbegin() == 0)
    std::cout << -1 << std::endl;
  else
    std::cout << A[0] - *dp[0][0].rbegin() << std::endl;
  return 0;
}