Problem p02733 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdint>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define N_TIMES(i, n) for (uint64_t i = 0; i < n; ++i)
#define N_TIMES_REV(i, n) for (int64_t i = n - 1; i >= 0; --i)

using namespace std;

uint64_t calc(uint64_t H, uint64_t W, uint64_t K,
              const vector<vector<uint64_t>> &C, const bitset<16> &bs) {
  uint64_t T = 0;

  // comporess vector
  vector<vector<uint64_t>> D;
  D.push_back(C[0]);
  N_TIMES(y, H - 1) {
    if (bs[y]) {
      D.push_back(C[y + 1]);
    } else {
      N_TIMES(x, W + 1) { D[D.size() - 1][x] += C[y + 1][x]; }
    }
  }

  auto binary_search = [&](uint64_t left) {
    auto judge = [&](uint64_t x) {
      N_TIMES(i, D.size()) {
        if ((D[i][x] - D[i][left]) > K) {
          return false;
        }
      }
      return true;
    };

    uint64_t lo = left, hi = W + 1;
    while (hi - lo > 1) {
      uint64_t mid = (hi + lo) >> 1;
      if (judge(mid)) {
        lo = mid;
      } else {
        hi = mid;
      }
    }
    return lo;
  };

  uint64_t L = 0;
  while (L < W) {
    L = binary_search(L);
    ++T;
  }

  return T - 1;
}

int main() {
  uint64_t H, W, K;
  cin >> H >> W >> K;

  vector<string> S(H);
  N_TIMES(y, H) { cin >> S[y]; }

  vector<vector<uint64_t>> C(H);
  N_TIMES(y, H) {
    C[y] = vector<uint64_t>(W + 1, 0);
    N_TIMES(x, W) { C[y][x + 1] = (S[y][x] - '0') + C[y][x]; }
  }

  uint64_t ans = 1e+9;
  N_TIMES(i, 1 << (H - 1)) {
    bitset<16> bs(i);

    uint64_t num_of_edge = bs.count() + calc(H, W, K, C, bs);
    ans = min(ans, num_of_edge);
  }
  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdint>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define N_TIMES(i, n) for (uint64_t i = 0; i < n; ++i)
#define N_TIMES_REV(i, n) for (int64_t i = n - 1; i >= 0; --i)

using namespace std;

uint64_t calc(uint64_t H, uint64_t W, uint64_t K,
              const vector<vector<uint64_t>> &C, const bitset<16> &bs) {
  uint64_t T = 0;

  // comporess vector
  vector<vector<uint64_t>> D;
  D.push_back(C[0]);
  N_TIMES(y, H - 1) {
    if (bs[y]) {
      D.push_back(C[y + 1]);
    } else {
      N_TIMES(x, W + 1) { D[D.size() - 1][x] += C[y + 1][x]; }
    }
  }

  auto binary_search = [&](uint64_t left) {
    auto judge = [&](uint64_t x) {
      N_TIMES(i, D.size()) {
        if ((D[i][x] - D[i][left]) > K) {
          return false;
        }
      }
      return true;
    };

    uint64_t lo = left, hi = W + 1;
    while (hi - lo > 1) {
      uint64_t mid = (hi + lo) >> 1;
      if (judge(mid)) {
        lo = mid;
      } else {
        hi = mid;
      }
    }
    return lo;
  };

  uint64_t L = 0;
  while (L < W) {
    uint64_t new_L = binary_search(L);
    if (L == new_L) {
      return 1e+9;
    }
    L = new_L;
    ++T;
  }

  return T - 1;
}

int main() {
  uint64_t H, W, K;
  cin >> H >> W >> K;

  vector<string> S(H);
  N_TIMES(y, H) { cin >> S[y]; }

  vector<vector<uint64_t>> C(H);
  N_TIMES(y, H) {
    C[y] = vector<uint64_t>(W + 1, 0);
    N_TIMES(x, W) { C[y][x + 1] = (S[y][x] - '0') + C[y][x]; }
  }

  uint64_t ans = 1e+9;
  N_TIMES(i, 1 << (H - 1)) {
    bitset<16> bs(i);

    uint64_t num_of_edge = bs.count() + calc(H, W, K, C, bs);
    ans = min(ans, num_of_edge);
  }
  cout << ans << endl;

  return 0;
}