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

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;

int main() {
  int h, w;
  while (scanf("%d%d", &h, &w) != EOF) {
    int k;
    scanf("%d", &k);
    static short int J[1000][1000], O[1000][1000], I[1000][1000];
    static short int size_j[1000], size_o[1000], size_i[1000];
    static short int J2[101][10000], O2[101][10000], I2[101][10000];
    static short int size_j2[101], size_o2[101], size_i2[101];
    for (int i = 0; i < h; i++) {
      size_j[i] = size_o[i] = size_i[i] = 0;
      if (i % 10 == 0)
        size_j2[i / 10] = size_o2[i / 10] = size_i2[i / 10] = 0;
      char str[1001];
      scanf("%s", str);
      for (int j = 0; j < w; j++) {
        if (str[j] == 'J') {
          J[i][size_j[i]++] = j;
          J2[i / 10][size_j2[i / 10]++] = j;
        } else if (str[j] == 'O') {
          O[i][size_o[i]++] = j;
          O2[i / 10][size_o2[i / 10]++] = j;
        } else if (str[j] == 'I') {
          I[i][size_i[i]++] = j;
          I2[i / 10][size_i2[i / 10]++] = j;
        }
      }
    }

    for (int i = 0; i <= h; i += 10) {
      sort(J2[i / 10], J2[i / 10] + size_j2[i / 10]);
      sort(O2[i / 10], O2[i / 10] + size_o2[i / 10]);
      sort(I2[i / 10], I2[i / 10] + size_i2[i / 10]);
    }

    int y1, x1, y2, x2;
    for (int i = 0; i < k; i++) {
      int ans_j = 0, ans_o = 0, ans_i = 0;
      scanf("%d%d%d%d", &y1, &x1, &y2, &x2);
      y1--;
      x1--;
      y2--;
      x2--;

      int j;
      for (j = y1; j <= y2; j++) {
        if (j % 10 == 0)
          break;
        ans_j += upper_bound(J[j], J[j] + size_j[j], x2) -
                 lower_bound(J[j], J[j] + size_j[j], x1);
        ans_o += upper_bound(O[j], O[j] + size_o[j], x2) -
                 lower_bound(O[j], O[j] + size_o[j], x1);
        ans_i += upper_bound(I[j], I[j] + size_i[j], x2) -
                 lower_bound(I[j], I[j] + size_i[j], x1);
      }

      for (; j + 10 <= y2; j += 10) {
        ans_j += upper_bound(J2[j / 10], J2[j / 10] + size_j2[j / 10], x2) -
                 lower_bound(J2[j / 10], J2[j / 10] + size_j2[j / 10], x1);
        ans_o += upper_bound(O2[j / 10], O2[j / 10] + size_o2[j / 10], x2) -
                 lower_bound(O2[j / 10], O2[j / 10] + size_o2[j / 10], x1);
        ans_i += upper_bound(I2[j / 10], I2[j / 10] + size_i2[j / 10], x2) -
                 lower_bound(I2[j / 10], I2[j / 10] + size_i2[j / 10], x1);
      }

      for (; j <= y2; j++) {
        ans_j += upper_bound(J[j], J[j] + size_j[j], x2) -
                 lower_bound(J[j], J[j] + size_j[j], x1);
        ans_o += upper_bound(O[j], O[j] + size_o[j], x2) -
                 lower_bound(O[j], O[j] + size_o[j], x1);
        ans_i += upper_bound(I[j], I[j] + size_i[j], x2) -
                 lower_bound(I[j], I[j] + size_i[j], x1);
      }

      printf("%d %d %d\\n", ans_j, ans_o, ans_i);
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;

int main() {
  int h, w;
  while (scanf("%d%d", &h, &w) != EOF) {
    int k;
    scanf("%d", &k);
    static short int J[1000][1000], O[1000][1000], I[1000][1000];
    static short int size_j[1000], size_o[1000], size_i[1000];
    for (int i = 0; i < h; i++) {
      size_j[i] = size_o[i] = size_i[i] = 0;
      char str[1001];
      scanf("%s", str);
      for (int j = 0; j < w; j++) {
        if (str[j] == 'J')
          J[i][size_j[i]++] = j;
        else if (str[j] == 'O')
          O[i][size_o[i]++] = j;
        else if (str[j] == 'I')
          I[i][size_i[i]++] = j;
      }
    }

    int y1, x1, y2, x2;
    for (int i = 0; i < k; i++) {
      int ans_j = 0, ans_o = 0, ans_i = 0;
      scanf("%d%d%d%d", &y1, &x1, &y2, &x2);
      y1--;
      x1--;
      y2--;
      x2--;
      for (int j = y1; j <= y2; j++) {
        ans_j += upper_bound(J[j], J[j] + size_j[j], x2) -
                 lower_bound(J[j], J[j] + size_j[j], x1);
        ans_o += upper_bound(O[j], O[j] + size_o[j], x2) -
                 lower_bound(O[j], O[j] + size_o[j], x1);
        ans_i += upper_bound(I[j], I[j] + size_i[j], x2) -
                 lower_bound(I[j], I[j] + size_i[j], x1);
      }
      printf("%d %d %d\\n", ans_j, ans_o, ans_i);
    }
  }
  return 0;
}