Problem p02733 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

// int/long:		-2,147,483,648 - 2,147,483,647 (-2^31 <= int < 2^31)
// long/long long:	-9,223,372,036,854,775,808 - 9,223,372,036,854,775,807
// (-2^63 <= long < 2^63)

// lower_bound(A.begin(), A.end(), N)
// upper_bound(...

// A.erase(unique(A.begin(), A.end()), A.end())

// bit: &/and, |/or, ^/xor, ~/not

// getline(cin, String)
// while (getline(cin, S)) {}

// #include <cstdio>
// int a;
// scanf("%d", &a);
// printf("%d\n", a);
//
// for (int i=0; i<n; ++i)
// 	scanf("%d", &a[i]);
//
// char c;
// scanf(" %c", &c);
//
// cout << "\n";

// cout <<fixed <<setprecision(10)

// priority_queue<int> q;
// priority_queue<int, vector<int>, less<int>> q; // Default: vector, less
// priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> q;

// Graph
// Warshall-Floyd: Distance between each node, N^3
// Dijkstra: Distance from the start node, N^2
// DFS(Depth-First Search)

//
// Notes
//
// When specified less than N, try full scan.
// RE: empty vector
// Check Qs
// long/int
// xor -> count each bit
// Check values
// 	1,000,000 -> Loop
// 	100,000	-> vector(int:400KB, long:800KB)

#define INF (1 << 30)
// 1,073,741,824
//= 536,870,912 *2

#define MOD 1000000007

/*
ll	myPow(ll x, ll n) {
        if (0==n)
                return 1;
        if (0==n%2)
                return myPow(x*x%MOD, n/2);
        else
                return x*myPow(x, n-1)%MOD;
}
*/
ll myPow(ll x, ll n) {
  ll r = 1;
  while (n > 0)
    if (0 == n % 2) {
      x *= x;
      x %= MOD;
      n /= 2;
    } else {
      r *= x;
      r %= MOD;
      n--;
    }
  return r;
}

#define Rep0(i, n) for (int i = 0; i < n; i++)
#define Rep1(i, n) for (int i = 1; i <= n; i++)
#define Sort(P) sort(P.begin(), P.end())
#define Rev(P) reverse(P.begin(), P.end())

int Count(const int x0, const int y0, const int x1, const int y1,
          const vector<vector<int>> &SUM) {
  return SUM.at(x1).at(y1) + SUM.at(x0).at(y0) - SUM.at(x1).at(y0) -
         SUM.at(x0).at(y1);
}

int main() {
  int H, W, K;
  cin >> H >> W >> K;
  vector<vector<int>> S(H + 1, vector<int>(W + 1, 0));
  Rep1(i, H) {
    string SS;
    cin >> SS;
    Rep1(j, W) S.at(i).at(j) = SS.at(j - 1) - '0';
  }
  // Input Done
  // cumulative sum table
  vector<vector<int>> CUSUM(H + 1, vector<int>(W + 2, 0));
  Rep1(i, H) {
    int s = 0;
    Rep1(j, W) {
      s += S.at(i).at(j);
      CUSUM.at(i).at(j) = CUSUM.at(i - 1).at(j) + s;
    }
    CUSUM.at(i).at(W + 1) = INF;
  }
  int SS = H + W;
  int M = pow(2, H - 1);
  Rep0(i, M) { // For each combination of holizontal lines
    vector<int> h;
    h.push_back(0);
    int SSS = 0; // Num of lines
    int I = i;
    int J = 1;
    while (I > 0) {
      if (1 == I % 2) {
        h.push_back(J);
        SSS++;
      }
      I /= 2;
      J *= 2;
    }
    h.push_back(H);
    // Count vertical lines
    int LL = 0;
    int RR = W + 1;
    bool FAIL = false;
    while (LL < W) { // Count vertical lines
      int RRR = W;
      Rep1(j, h.size() - 1) {
        int h0 = h.at(j - 1);
        int h1 = h.at(j);
        int L = LL;
        int R = RR;
        while (R - L > 1) {
          int M = (L + R) / 2;
          if (Count(h0, LL, h1, M, CUSUM) > K)
            R = M;
          else
            L = M;
        }
        if (L == LL) { // Not possible
          FAIL = true;
          break;
        }
        RRR = min(RRR, L);
      }
      if (FAIL)
        break;
      if (RRR < W) // Add vertical line after L
        SSS++;
      LL = RRR;
    }
    if (FAIL)
      continue;
    SS = min(SS, SSS);
  }
  cout << SS << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

// int/long:		-2,147,483,648 - 2,147,483,647 (-2^31 <= int < 2^31)
// long/long long:	-9,223,372,036,854,775,808 - 9,223,372,036,854,775,807
// (-2^63 <= long < 2^63)

// lower_bound(A.begin(), A.end(), N)
// upper_bound(...

// A.erase(unique(A.begin(), A.end()), A.end())

// bit: &/and, |/or, ^/xor, ~/not

// getline(cin, String)
// while (getline(cin, S)) {}

// #include <cstdio>
// int a;
// scanf("%d", &a);
// printf("%d\n", a);
//
// for (int i=0; i<n; ++i)
// 	scanf("%d", &a[i]);
//
// char c;
// scanf(" %c", &c);
//
// cout << "\n";

// cout <<fixed <<setprecision(10)

// priority_queue<int> q;
// priority_queue<int, vector<int>, less<int>> q; // Default: vector, less
// priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> q;

// Graph
// Warshall-Floyd: Distance between each node, N^3
// Dijkstra: Distance from the start node, N^2
// DFS(Depth-First Search)

//
// Notes
//
// When specified less than N, try full scan.
// RE: empty vector
// Check Qs
// long/int
// xor -> count each bit
// Check values
// 	1,000,000 -> Loop
// 	100,000	-> vector(int:400KB, long:800KB)

#define INF (1 << 30)
// 1,073,741,824
//= 536,870,912 *2

#define MOD 1000000007

/*
ll	myPow(ll x, ll n) {
        if (0==n)
                return 1;
        if (0==n%2)
                return myPow(x*x%MOD, n/2);
        else
                return x*myPow(x, n-1)%MOD;
}
*/
ll myPow(ll x, ll n) {
  ll r = 1;
  while (n > 0)
    if (0 == n % 2) {
      x *= x;
      x %= MOD;
      n /= 2;
    } else {
      r *= x;
      r %= MOD;
      n--;
    }
  return r;
}

#define Rep0(i, n) for (int i = 0; i < n; i++)
#define Rep1(i, n) for (int i = 1; i <= n; i++)
#define Sort(P) sort(P.begin(), P.end())
#define Rev(P) reverse(P.begin(), P.end())

int Count(const int x0, const int y0, const int x1, const int y1,
          const vector<vector<int>> &SUM) {
  return SUM.at(x1).at(y1) + SUM.at(x0).at(y0) - SUM.at(x1).at(y0) -
         SUM.at(x0).at(y1);
}

int main() {
  int H, W, K;
  cin >> H >> W >> K;
  vector<vector<int>> S(H + 1, vector<int>(W + 1, 0));
  Rep1(i, H) {
    string SS;
    cin >> SS;
    Rep1(j, W) S.at(i).at(j) = SS.at(j - 1) - '0';
  }
  // Input Done
  // cumulative sum table
  vector<vector<int>> CUSUM(H + 1, vector<int>(W + 2, 0));
  Rep1(i, H) {
    int s = 0;
    Rep1(j, W) {
      s += S.at(i).at(j);
      CUSUM.at(i).at(j) = CUSUM.at(i - 1).at(j) + s;
    }
    CUSUM.at(i).at(W + 1) = INF;
  }
  int SS = H + W;
  int M = pow(2, H - 1);
  Rep0(i, M) { // For each combination of holizontal lines
    vector<int> h;
    h.push_back(0);
    int SSS = 0; // Num of lines
    int I = i;
    int J = 1;
    while (I > 0) {
      if (1 == I % 2) {
        h.push_back(J);
        SSS++;
      }
      I /= 2;
      J++;
    }
    h.push_back(H);
    // Count vertical lines
    int LL = 0;
    int RR = W + 1;
    bool FAIL = false;
    while (LL < W) { // Count vertical lines
      int RRR = W;
      Rep1(j, h.size() - 1) {
        int h0 = h.at(j - 1);
        int h1 = h.at(j);
        int L = LL;
        int R = RR;
        while (R - L > 1) {
          int M = (L + R) / 2;
          if (Count(h0, LL, h1, M, CUSUM) > K)
            R = M;
          else
            L = M;
        }
        if (L == LL) { // Not possible
          FAIL = true;
          break;
        }
        RRR = min(RRR, L);
      }
      if (FAIL)
        break;
      if (RRR < W) // Add vertical line after L
        SSS++;
      LL = RRR;
    }
    if (FAIL)
      continue;
    SS = min(SS, SSS);
  }
  cout << SS << endl;
  return 0;
}