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

#include <algorithm>
#include <iostream>

using namespace std;

typedef long long ll;

struct Piece {
  int top;
  int end;
  ll size;
};

class Baumkuchen {
private:
  int N;
  const int DevideNum;
  ll *A;
  ll *sum;
  Piece *piece;

  void input();
  void newArrays(int n);
  void setSum();
  bool isContainPiece(int i, const Piece &p);
  ll calcPieceSize(const Piece &p);
  Piece cutDivideBaumkuchen(int _top, int _end, ll min_piece_size);
  bool cutOK(ll min_piece_size);

public:
  Baumkuchen(int _DevideNum);
  ~Baumkuchen();

  ll solve();
};

Baumkuchen::Baumkuchen(int _DevideNum) : N(0), DevideNum(_DevideNum) {
  A = NULL;
  sum = NULL;
  piece = NULL;
}

Baumkuchen::~Baumkuchen() {
  delete[] A;
  delete[] sum;
  delete[] piece;
}

void Baumkuchen::newArrays(int n) {
  A = new ll[n];
  sum = new ll[2 * n + 1];
  piece = new Piece[DevideNum];
}

void Baumkuchen::input() {
  cin >> N;
  newArrays(N);

  for (int i = 0; i < N; i++)
    cin >> A[i];
}

void Baumkuchen::setSum() {
  sum[0] = A[0];
  for (int i = 1; i < N; i++)
    sum[i] = sum[i - 1] + A[i];

  for (int i = 0; i < N; i++)
    sum[i + N] = sum[i] + sum[N - 1];
}

bool Baumkuchen::isContainPiece(int i, const Piece &p) {
  return (p.top <= i % N && i % N <= p.end) ||
         (p.top <= (i % N) + N && (i % N) + N <= p.end);
}

ll Baumkuchen::calcPieceSize(const Piece &p) {
  return (p.top <= p.end) ? (sum[p.end] - sum[p.top] + A[p.top % N]) : -1;
}

Piece Baumkuchen::cutDivideBaumkuchen(int _top, int _end, ll min_piece_size) {
  Piece p;
  p.top = _top;
  p.end = _end;

  if (calcPieceSize(p) < min_piece_size) {
    p.size = -1;
    return p;
  }

  int end_max = _end, end_min = _top;

  while (end_max > end_min + 1) {
    p.end = (end_max + end_min) / 2;
    if (calcPieceSize(p) < min_piece_size)
      end_min = p.end;
    else
      end_max = p.end;
  }
  p.end = end_min;
  p.end = calcPieceSize(p) < min_piece_size ? end_max : end_min;
  p.size = calcPieceSize(p);

  return p;
}

bool Baumkuchen::cutOK(ll min_piece_size) {
  piece[0] = cutDivideBaumkuchen(0, N - 1, min_piece_size);
  if (piece[0].size == -1)
    return false;

  int cp = piece[0].end;

  for (; isContainPiece(cp, piece[0]); piece[0].top++) {
    piece[0] = cutDivideBaumkuchen(piece[0].top, N - 1, min_piece_size);
    for (int pieceNum = 1; pieceNum < DevideNum; pieceNum++) {
      piece[pieceNum] =
          cutDivideBaumkuchen(piece[pieceNum - 1].end + 1,
                              (piece[0].top) % N + N - 1, min_piece_size);
      if (piece[pieceNum].size == -1)
        goto MISS;
    }
    //		cout << min_piece_size << " : " << piece[0].top << ", " <<
    //piece[0].end << ", " << piece[0].size << " | " << piece[1].top << ", " <<
    //piece[1].end << ", " << piece[1].size << " | " << piece[2].top << ", " <<
    //piece[2].end << ", " << piece[2].size << endl;
    return true;

  MISS:
    //		piece[2].size = calcPieceSize(piece[2]);
    //		cout << min_piece_size << " : " << piece[0].top << ", " <<
    //piece[0].end << ", " << piece[0].size << " | " << piece[1].top << ", " <<
    //piece[1].end << ", " << piece[1].size << " | " << piece[2].top << ", " <<
    //piece[2].end << ", " << piece[2].size << endl;
    continue;
  }
  return false;
}

ll Baumkuchen::solve() {
  input();
  setSum();

  ll ans;
  ll ans_max = sum[N - 1] / 3;
  ll ans_min = 0;

  while (ans_max > ans_min + 1) {
    ans = (ans_max + ans_min) / 2;
    if (cutOK(ans))
      ans_min = ans;
    else
      ans_max = ans;
  }
  ans = (cutOK(ans_min)) ? ans_min : ans_max;

  return ans;
}

int main() {
  Baumkuchen *baumkuchen = new Baumkuchen(3);

  ll ans = baumkuchen->solve();
  cout << ans << endl;

  delete baumkuchen;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>

using namespace std;

typedef long long ll;

struct Piece {
  int top;
  int end;
  ll size;
};

class Baumkuchen {
private:
  int N;
  const int DevideNum;
  ll *A;
  ll *sum;
  Piece *piece;

  void input();
  void newArrays(int n);
  void setSum();
  bool isContainPiece(int i, const Piece &p);
  ll calcPieceSize(const Piece &p);
  Piece cutDivideBaumkuchen(int _top, int _end, ll min_piece_size);
  bool cutOK(ll min_piece_size);

public:
  Baumkuchen(int _DevideNum);
  ~Baumkuchen();

  ll solve();
};

Baumkuchen::Baumkuchen(int _DevideNum) : N(0), DevideNum(_DevideNum) {
  A = NULL;
  sum = NULL;
  piece = NULL;
}

Baumkuchen::~Baumkuchen() {
  delete[] A;
  delete[] sum;
  delete[] piece;
}

void Baumkuchen::newArrays(int n) {
  A = new ll[n];
  sum = new ll[2 * n];
  piece = new Piece[DevideNum];
}

void Baumkuchen::input() {
  cin >> N;
  newArrays(N);

  for (int i = 0; i < N; i++)
    cin >> A[i];
}

void Baumkuchen::setSum() {
  sum[0] = A[0];
  for (int i = 1; i < N; i++)
    sum[i] = sum[i - 1] + A[i];

  for (int i = 0; i < N; i++)
    sum[i + N] = sum[i] + sum[N - 1];
}

bool Baumkuchen::isContainPiece(int i, const Piece &p) {
  return (p.top <= i % N && i % N <= p.end) ||
         (p.top <= (i % N) + N && (i % N) + N <= p.end);
}

ll Baumkuchen::calcPieceSize(const Piece &p) {
  return (p.top <= p.end) ? (sum[p.end] - sum[p.top] + A[p.top % N]) : -1;
}

Piece Baumkuchen::cutDivideBaumkuchen(int _top, int _end, ll min_piece_size) {
  Piece p;
  p.top = _top;

  for (p.end = p.top; p.end <= _end; p.end++) {
    if ((p.size = calcPieceSize(p)) >= min_piece_size)
      return p;
  }

  p.end--;
  p.size = -1;
  return p;
}

bool Baumkuchen::cutOK(ll min_piece_size) {
  piece[0] = cutDivideBaumkuchen(0, N - 1, min_piece_size);
  if (piece[0].size == -1)
    return false;

  int cp = piece[0].end;

  for (; isContainPiece(cp, piece[0]); piece[0].top++) {
    piece[0] = cutDivideBaumkuchen(piece[0].top, N - 1, min_piece_size);
    for (int pieceNum = 1; pieceNum < DevideNum; pieceNum++) {
      piece[pieceNum] =
          cutDivideBaumkuchen(piece[pieceNum - 1].end + 1,
                              (piece[0].top) % N + N - 1, min_piece_size);
      if (piece[pieceNum].size == -1)
        goto MISS;
    }
    //		cout << min_piece_size << " : " << piece[0].top << ", " <<
    //piece[0].end << ", " << piece[0].size << " | " << piece[1].top << ", " <<
    //piece[1].end << ", " << piece[1].size << " | " << piece[2].top << ", " <<
    //piece[2].end << ", " << piece[2].size << endl;
    return true;

  MISS:
    //		piece[2].size = calcPieceSize(piece[2]);
    //		cout << min_piece_size << " : " << piece[0].top << ", " <<
    //piece[0].end << ", " << piece[0].size << " | " << piece[1].top << ", " <<
    //piece[1].end << ", " << piece[1].size << " | " << piece[2].top << ", " <<
    //piece[2].end << ", " << piece[2].size << endl;
    continue;
  }
  return false;
}

ll Baumkuchen::solve() {
  input();
  setSum();

  ll ans;
  ll ans_max = sum[N - 1] / 3;
  ll ans_min = 0;

  while (ans_max > ans_min + 1) {
    ans = (ans_max + ans_min) / 2;
    if (cutOK(ans))
      ans_min = ans;
    else
      ans_max = ans;
  }
  ans = (cutOK(ans_min)) ? ans_min : ans_max;

  return ans;
}

int main() {
  Baumkuchen *baumkuchen = new Baumkuchen(3);

  ll ans = baumkuchen->solve();
  cout << ans << endl;

  delete baumkuchen;
  return 0;
}