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

#include <algorithm>
#include <iostream>

using namespace std;
typedef unsigned long long ull;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N; // 切れ込みの個数
  cin >> N;

  int *A = new int[N]; // 各ピースの大きさを格納する配列
  ull total_size = 0;  // バームクーヘンの大きさ
  int i1_ini = 0;
  int A_max = 0;
  for (int i = 0; i < N; i++) {
    cin >> A[i];
    total_size += A[i];
    if (A[i] > A_max) {
      A_max = A[i];
      i1_ini = i;
    }
  }
  ull one_third_size = total_size / 3;
  ull answer = 0;
  if (A_max > one_third_size) {
    ull half_size = (total_size - A_max) / 2;
    ull tmp = 0;
    ull piece2 = 0;
    for (int i3 = i1_ini + 1; i3 < i1_ini + N - 1; i3++) {
      piece2 = tmp;
      tmp += A[i3 % N];
      if (tmp > half_size)
        break;
    }
    ull piece3 = total_size - A_max - tmp;
    answer = max(piece2, piece3);
    cout << answer << endl;
    return 0;
  }

  int i2 = i1_ini;
  ull piece1_s = 0;
  ull piece1_l = 0;
  for (; i2 < i1_ini + N - 2;) {
    piece1_s = piece1_l;
    piece1_l += A[i2 % N];
    i2++;
    if (piece1_l > one_third_size)
      break;
  }
  const int i1_fin = i2;

  int i3 = i1_ini + N;
  ull piece3_s = 0;
  ull piece3_l = 0;
  for (; i3 > i2 + 1;) {
    piece3_s = piece3_l;
    i3--;
    piece3_l += A[i3 % N];
    if (piece3_l > one_third_size)
      break;
  }
  i3++;

  ull tmp = 0;
  tmp = min(piece1_s, piece3_s);

  ull piece2 = 0;
  piece2 = total_size - piece1_s - piece3_l;
  tmp = max(tmp, min(piece1_s, piece2));

  piece2 = total_size - piece1_l - piece3_s;
  tmp = max(tmp, min(piece3_s, piece2));

  piece2 = total_size - piece1_l - piece3_l;
  tmp = max(tmp, piece2);

  answer = tmp;

  for (int i1 = i1_ini + 1; i1 < i1_fin; i1++) {
    int A_tmp = A[(i1 - 1) % N];
    piece1_l -= A_tmp;
    if (piece1_l > one_third_size)
      piece1_s -= A_tmp;
    else {
      for (; i2 < i1 + N - 2;) {
        piece1_s = piece1_l;
        piece1_l += A[i2 % N];
        i2++;
        if (piece1_l > one_third_size)
          break;
      }
    }

    piece3_s += A_tmp;
    if (piece3_s <= one_third_size)
      piece3_l += A_tmp;
    else {
      for (; i3 < i1 + N - 1;) {
        piece3_l = piece3_s;
        piece3_s -= A[i3 % N];
        i3++;
        if (piece3_s <= one_third_size)
          break;
      }
    }

    tmp = min(piece1_s, piece3_s);

    piece2 = total_size - piece1_s - piece3_l;
    tmp = max(tmp, min(piece1_s, piece2));

    piece2 = total_size - piece1_l - piece3_s;
    tmp = max(tmp, min(piece3_s, piece2));

    piece2 = total_size - piece1_l - piece3_l;
    tmp = max(tmp, piece2);

    answer = max(answer, tmp);
  }

  cout << answer << endl;

  delete[] A;

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>

using namespace std;
typedef unsigned long long ull;

int CalcPiece1(int _i2, ull *_piece1, const int _N, const int _i1,
               const ull _one_third_size, const int *_A) {
  for (; _i2 < _i1 + _N - 2;) {
    *_piece1 += _A[_i2 % _N];
    _i2++;
    if (*_piece1 >= _one_third_size)
      break;
  }
  return _i2;
}

ull CalcMinimunPiece(const int _i1, const int _i2, const int _N, const int *_A,
                     const ull _half_size, const ull _two_third_size) {
  ull piece2 = 0;
  ull tmp = 0;
  for (int i3 = _i2; i3 < _i1 + _N - 1; i3++) {
    piece2 = tmp;
    tmp += _A[i3 % _N];
    if (tmp > _half_size)
      break;
  }
  if (tmp <= _half_size)
    return tmp;
  ull piece3 = _two_third_size - tmp;

  if (piece2 > piece3)
    tmp = piece2;
  else
    tmp = piece3;

  return tmp;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N; // 切れ込みの個数
  cin >> N;

  /*
  int *A = new int[N];	//各ピースの大きさを格納する配列
  ull total_size = 0;	//バームクーヘンの大きさ
  for(int i=0; i<N; i++){
          cin >> A[i];
          total_size += A[i];
  }
  ull one_third_size;
  if(total_size % 3 == 0) one_third_size = total_size / 3;
  else one_third_size = total_size / 3 + 1;

  ull answer = 0;

  for(int i1=0; i1<N; i1++){
          ull piece1 = 0;
          int i2;
          for(i2=i1; i2<i1-2+N; i2++){
                  piece1 += A[i2%N];
                  if(piece1 >= one_third_size) break;
          }
          if(piece1 < one_third_size) continue;
          i2++;

          ull two_third_size = total_size - piece1;
          ull half_size;
          if(two_third_size % 2 == 0) half_size = two_third_size / 2;
          else half_size = two_third_size / 2 + 1;

          ull tmp = 0;
          for(int i3=i1-1+N; i3>i2; i3--){
                  tmp += A[i3%N];
                  if(tmp >= half_size) break;
          }
          if(tmp < half_size){
                  if(tmp > answer) answer = tmp;
                  continue;
          }
          ull piece2 = two_third_size - tmp;

          tmp = 0;
          for(int i3=i2; i3<i1-1+N; i3++){
                  tmp += A[i3%N];
                  if(tmp >= half_size) break;
          }
          if(tmp < half_size){
                  if(tmp > answer) answer = tmp;
                  continue;
          }
          ull piece3 = two_third_size - tmp;

          if(piece2 > piece3) tmp = piece2;
          else tmp = piece3;

          if(tmp > answer) answer = tmp;
  }

  delete[] A;

  cout << answer << endl;
  /*/
  int *A = new int[N];
  ull total_size = 0;
  int A_max = 0;
  int i1 = 0;
  for (int i = 0; i < N; i++) {
    cin >> A[i];
    total_size += A[i];
    if (A[i] > A_max) {
      A_max = A[i];
      i1 = i;
    }
  }

  ull one_third_size;
  if (total_size % 3 == 0)
    one_third_size = total_size / 3;
  else
    one_third_size = total_size / 3 + 1;

  ull piece1 = 0;
  int i2 = i1;
  i2 = CalcPiece1(i2, &piece1, N, i1, one_third_size, A);
  /*for( ; i2<i1+N-2; ){
          piece1 += A[i2%N];
          i2++;
          if(piece1 >= one_third_size) break;
  }*/

  ull two_third_size = total_size - piece1;
  ull half_size = two_third_size / 2;

  ull answer = 0;
  if (A[i2 % N] > half_size)
    answer = two_third_size - A[i2 % N];
  else {
    /*ull piece2 = 0;
    ull tmp = 0;
    for(int i3=i2+1; i3<i1+N; i3++){
            piece2 = tmp;
            tmp += A[(i3-1)%N];
            if(tmp > half_size) break;
    }
    ull piece3 = two_third_size - tmp;

    if(piece2 > piece3) tmp = piece2;
    else tmp = piece3;
    answer = tmp;*/
    answer = CalcMinimunPiece(i1, i2, N, A, half_size, two_third_size);
  }

  for (int i = i1 + 1; i < i1 + N; i++) {
    piece1 -= A[(i - 1) % N];
    if (piece1 < one_third_size) {
      i2 = CalcPiece1(i2, &piece1, N, i, one_third_size, A);
      /*for( ; i2<i+N-2; ){
              piece1 += A[i2%N];
              i2++;
              if(piece1 >= one_third_size) break;
      }*/
    }

    two_third_size = total_size - piece1;
    half_size = two_third_size / 2;

    if (A[i2 % N] > half_size) {
      ull piece3 = two_third_size - A[i2 % N];
      if (piece3 > answer)
        answer = piece3;
    } else {
      /*ull piece2 = 0;
      ull tmp = 0;
      for(int i3=i2+1; i3<i+N; i3++){
              piece2 = tmp;
              tmp += A[(i3-1)%N];
              if(tmp > half_size) break;
      }
      ull piece3 = two_third_size - tmp;

      if(piece2 > piece3) tmp = piece2;
      else tmp = piece3;*/
      ull tmp = CalcMinimunPiece(i, i2, N, A, half_size, two_third_size);
      if (tmp > answer)
        answer = tmp;
    }
  }
  delete[] A;

  cout << answer << endl;
  //*/

  return 0;
}