Problem p03707 (C++)

Buggy submission (status: Runtime Error):
/*
这道题怎么这么熟悉哈
简单的转化， 答案等于块内蓝格子数量减去块内每个点非向外连得度数


蓝格子数量可以直接二位前缀和求
非向外连得度数？？ 这个怎么求， 对于每一行每一列都维护向左向右的前缀和即可

正解应该不是这样吧QWQ


*/

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define ll long long
#define M 1011
using namespace std;
int read() {
  int nm = 0, f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-')
      f = -1;
  for (; isdigit(c); c = getchar())
    nm = nm * 10 + c - '0';
  return nm * f;
}

int hu[M][M], hd[M][M], lx[M][M], ly[M][M], sum[M][M], du[M][M];
char s[M];
int note[M][M];
int q, n, m;
int main() {
  n = read(), m = read(), q = read();
  for (int i = 1; i <= n; i++) {
    scanf("%s", s + 1);
    for (int j = 1; j <= m; j++)
      note[i][j] = s[j] - '0';
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + note[i][j];
      if (note[i][j]) {
        if (note[i - 1][j])
          du[i][j]++;
        if (note[i + 1][j])
          du[i][j]++;
        if (note[i][j - 1])
          du[i][j]++;
        if (note[i][j + 1])
          du[i][j]++;
      }
      du[i][j] += du[i - 1][j] + du[i][j - 1] - du[i - 1][j - 1];
    }
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      hu[i][j] = hu[i][j - 1] + (note[i][j] && note[i - 1][j]);
      hd[i][j] = hd[i][j - 1] + (note[i][j] && note[i + 1][j]);
      lx[i][j] = lx[i - 1][j] + (note[i][j] && note[i][j - 1]);
      ly[i][j] = ly[i - 1][j] + (note[i][j] && note[i][j + 1]);
    }
  while (q--) {
    int a = read(), b = read(), c = read(), d = read();
    int op = (du[c][d] - du[a - 1][d] - du[c][b - 1] + du[a - 1][b - 1]) -
             (hu[a][d] - hu[a][b - 1] + hd[c][d] - hd[c][b - 1] + lx[c][b] -
              lx[a - 1][b] + ly[c][d] - ly[a - 1][d]);
    int od = sum[c][d] - sum[a - 1][d] - sum[c][b - 1] + sum[a - 1][b - 1];
    //	cout << od << " " << op << "\n";
    cout << od - op / 2 << "\n";
  }
  return 0;
}

Fixed submission:
/*
这道题怎么这么熟悉哈
简单的转化， 答案等于块内蓝格子数量减去块内每个点非向外连得度数


蓝格子数量可以直接二位前缀和求
非向外连得度数？？ 这个怎么求， 对于每一行每一列都维护向左向右的前缀和即可

正解应该不是这样吧QWQ


*/

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define ll long long
#define M 2011
using namespace std;
int read() {
  int nm = 0, f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-')
      f = -1;
  for (; isdigit(c); c = getchar())
    nm = nm * 10 + c - '0';
  return nm * f;
}

int hu[M][M], hd[M][M], lx[M][M], ly[M][M], sum[M][M], du[M][M];
char s[M];
int note[M][M];
int q, n, m;
int main() {
  n = read(), m = read(), q = read();
  for (int i = 1; i <= n; i++) {
    scanf("%s", s + 1);
    for (int j = 1; j <= m; j++)
      note[i][j] = s[j] - '0';
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + note[i][j];
      if (note[i][j]) {
        if (note[i - 1][j])
          du[i][j]++;
        if (note[i + 1][j])
          du[i][j]++;
        if (note[i][j - 1])
          du[i][j]++;
        if (note[i][j + 1])
          du[i][j]++;
      }
      du[i][j] += du[i - 1][j] + du[i][j - 1] - du[i - 1][j - 1];
    }
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      hu[i][j] = hu[i][j - 1] + (note[i][j] && note[i - 1][j]);
      hd[i][j] = hd[i][j - 1] + (note[i][j] && note[i + 1][j]);
      lx[i][j] = lx[i - 1][j] + (note[i][j] && note[i][j - 1]);
      ly[i][j] = ly[i - 1][j] + (note[i][j] && note[i][j + 1]);
    }
  while (q--) {
    int a = read(), b = read(), c = read(), d = read();
    int op = (du[c][d] - du[a - 1][d] - du[c][b - 1] + du[a - 1][b - 1]) -
             (hu[a][d] - hu[a][b - 1] + hd[c][d] - hd[c][b - 1] + lx[c][b] -
              lx[a - 1][b] + ly[c][d] - ly[a - 1][d]);
    int od = sum[c][d] - sum[a - 1][d] - sum[c][b - 1] + sum[a - 1][b - 1];
    //	cout << od << " " << op << "\n";
    cout << od - op / 2 << "\n";
  }
  return 0;
}