Submission #787503

# Submission time Handle Problem Language Result Execution time Memory
787503 2023-07-19T08:41:46 Z WLZ Sandcastle 2 (JOI22_ho_t5) C++17
0 / 100
5000 ms 51900 KB
#include <bits/stdc++.h>
using namespace std;
 
const int INF = 0x3f3f3f3f;

const vector<int> dx = {1, -1, 0, 0};
const vector<int> dy = {0, 0, 1, -1};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int h, w;
  cin >> h >> w;
  vector< vector<int> > grid(h + 2, vector<int>(w + 2));
  map<int, int> cmp_mp;
  for (int i = 1; i <= h; i++) for (int j = 1; j <= w; j++) cin >> grid[i][j], cmp_mp[grid[i][j]] = -1;
  int cnt = 1;
  for (auto &p : cmp_mp) p.second = cnt++;
  for (int i = 1; i <= h; i++) for (int j = 1; j <= w; j++) grid[i][j] = cmp_mp[grid[i][j]];
  /*if (h < w) {
    vector< vector<int> > grid2(w + 2, vector<int>(h + 2));
    for (int i = 1; i <= h; i++) for (int j = 1; j <= w; j++) grid2[j][i] = grid[i][j];
    swap(grid2, grid); swap(h, w);
  }*/
  vector< vector< vector<int> > > in_deg(81, vector< vector<int> >(h + 2, vector<int>(w + 2, 0)));
  vector< vector<int> > used(h + 2, vector<int>(w + 2, 0));
  for (int type = 0; type < 81; type++) {
    vector<int> t(4);
    for (int i = 0, tmp = type; i < 4; i++) t[i] = tmp % 3, tmp /= 3;
    for (int r = 1; r <= h; r++) {
      for (int c = 1; c <= w; c++) {
        vector< pair<int, int> > neighbors, extra;
        used[r][c] = 1;
        for (int k = 0; k < 4; k++) {
          for (int i = 1; i <= t[k]; i++) {
            int nr = r + i * dx[k], nc = c + i * dy[k];
            if (nr >= 1 && nr <= h && nc >= 1 && nc <= w) {
              if (i == 1) neighbors.emplace_back(nr, nc);
              used[nr][nc] = 1;
              extra.emplace_back(nr, nc);
            }
          }
        }
        for (int nr = max(1, r - 2); nr <= min(h, r + 2); nr++) {
          for (int nc = max(1, c - 2); nc <= min(w, c + 2); nc++) {
            if (used[r][nc] && used[nr][c]) {
              used[nr][nc] = 1;
              extra.emplace_back(nr, nc);
            }
          }
        }
        for (auto &p : neighbors) {
          int nr = p.first, nc = p.second;
          int mx = -INF, mx_r = -1, mx_c = -1;
          for (int k = 0; k < 4; k++) {
            int nnr = nr + dx[k], nnc = nc + dy[k];
            if (nnr >= 1 && nnr <= h && nnc >= 1 && nnc <= w && used[nnr][nnc] && grid[nnr][nnc] < grid[nr][nc] && grid[nnr][nnc] > mx) {
              mx = grid[nnr][nnc];
              mx_r = nnr, mx_c = nnc;
            } 
          }
          in_deg[type][r][c] += (mx_r == r && mx_c == c);
        }
        for (auto &p : extra) used[p.first][p.second] = 0;
        used[r][c] = 0;
        in_deg[type][r][c] = (1 ? in_deg[type][r][c] == 0 : 0);
      }
    }
  }
  for (int type = 0; type < 81; type++) {
    for (int r = 1; r <= h; r++) for (int c = 1; c <= w; c++) in_deg[type][r][c] += in_deg[type][r - 1][c] + in_deg[type][r][c - 1] - in_deg[type][r - 1][c - 1];
  }

  auto get_sum = [&](int type, int r1, int c1, int r2, int c2) {
    if (r2 < r1 || c2 < c1) return 0;
    return in_deg[type][r2][c2] - in_deg[type][r1 - 1][c2] - in_deg[type][r2][c1 - 1] + in_deg[type][r1 - 1][c1 - 1];
  };

  auto brute_force = [&](int r1, int c1, int r2, int c2) {
    int r = r1, c = c1;
    for (int nr = r1; nr <= r2; nr++) for (int nc = c1; nc <= c2; nc++) if (grid[nr][nc] > grid[r][c]) r = nr, c = nc;
    int cnt = 0;
    while (true) {
      cnt++;
      int mx = -INF, nr = -1, nc = -1;
      for (int k = 0; k < 4; k++) {
        int nnr = r + dx[k], nnc = c + dy[k];
        if (nnr >= r1 && nnr <= r2 && nnc >= c1 && nnc <= c2 && grid[nnr][nnc] < grid[r][c] && grid[nnr][nnc] > mx) {
          mx = grid[nnr][nnc];
          nr = nnr, nc = nnc;
        } 
      }
      r = nr, c = nc;
      if (mx == -INF) break;
    }
    return cnt == (r2 - r1 + 1) * (c2 - c1 + 1);
  };
  int ans = 0;
  for (int r1 = 1; r1 <= h; r1++) {
    for (int c1 = 1; c1 <= w; c1++) {
      for (int r2 = r1; r2 <= h; r2++) {
        for (int c2 = c1; c2 <= w; c2++) {
          if (r2 - r1 <= 2 && c2 - c1 <= 2) {
            ans += brute_force(r1, c1, r2, c2);
            continue;
          }
          //cerr << r1 << ' ' << c1 << ' ' << r2 << ' ' << c2 << endl;
          if (r1 == r2) {
            ans += (get_sum(18, r1, c1, r1, c1) + get_sum(45, r1, c1 + 1, r1, c1 + 1) 
            + get_sum(72, r1, c1 + 2, r1, c2 - 2) + get_sum(63, r1, c2 - 1, r1, c2 - 1) + get_sum(54, r1, c2, r1, c2) == 1);
          } else if (c1 == c2) {
            ans += (get_sum(2, r1, c1, r1, c1) + get_sum(5, r1 + 1, c1, r1 + 1, c1)
            + get_sum(8, r1 + 2, c1, r2 - 2, c1) + get_sum(7, r2 - 1, c1, r2 - 1, c1) + get_sum(6, r2, c1, r2, c1) == 1);
          } else if (r1 + 1 == r2) {
            ans += (get_sum(19, r1, c1, r1, c1) + get_sum(46, r1, c1 + 1, r1, c1 + 1) + get_sum(73, r1, c1 + 2, r1, c2 - 2) + get_sum(64, r1, c2 - 1, r1, c2 - 1) + get_sum(55, r1, c2, r1, c2)
            + get_sum(21, r2, c1, r2, c1) + get_sum(48, r2, c1 + 1, r2, c1 + 1) + get_sum(75, r2, c1 + 2, r2, c2 - 2) + get_sum(66, r2, c2 - 1, r2, c2 - 1) + get_sum(57, r2, c2, r2, c2) == 1);
          } else if (c1 + 1 == c2) {  
            ans += (get_sum(11, r1, c1, r1, c1) + get_sum(29, r1, c2, r1, c2) + get_sum(14, r1 + 1, c1, r1 + 1, c1) + get_sum(32, r1 + 1, c2, r1 + 1, c2) + get_sum(17, r1 + 2, c1, r2 - 2, c1) + get_sum(35, r1 + 2, c2, r2 - 2, c2)
            + get_sum(16, r2 - 1, c1, r2 - 1, c1) + get_sum(34, r2 - 1, c2, r2 - 1, c2) + get_sum(15, r2, c1, r2, c1) + get_sum(33, r2, c2, r2, c2) == 1);
          } else {
            ans += (get_sum(20, r1, c1, r1, c1) + get_sum(56, r1, c2, r1, c2) + get_sum(24, r2, c1, r2, c1) + get_sum(60, r2, c2, r2, c2) // corners
            + get_sum(47, r1, c1 + 1, r1, c1 + 1) + get_sum(65, r1, c2 - 1, r1, c2 - 1) + get_sum(23, r1 + 1, c1, r1 + 1, c1) + get_sum(59, r1 + 1, c2, r1 + 1, c2)
            + get_sum(25, r2 - 1, c1, r2 - 1, c1) + get_sum(61, r2 - 1, c2, r2 - 1, c2) + get_sum(51, r2, c1 + 1, r2, c1 + 1) + get_sum(69, r2, c2 - 1, r2, c2 - 1)
            + get_sum(50, r1 + 1, c1 + 1, r1 + 1, c1 + 1) + get_sum(68, r1 + 1, c2 - 1, r1 + 1, c2 - 1) 
            + get_sum(52, r2 - 1, c1 + 1, c2 - 1, c1 + 1) + get_sum(70, r2 - 1, c2 - 1, r2 - 1, c2 - 1) // inner corners
            + get_sum(74, r1, c1 + 2, r1, c2 - 2) + get_sum(78, r2, c1 + 2, r2, c2 - 2) + get_sum(26, r1 + 2, c1, r2 - 2, c1) + get_sum(62, r1 + 2, c2, r2 - 2, c2) // edges
            + get_sum(77, r1 + 1, c1 + 2, r1 + 1, c2 - 2) + get_sum(79, r2 - 1, c1 + 2, r2 - 1, c2 - 2)
            + get_sum(53, r1 + 2, c1 + 1, r2 - 2, c1 + 1) + get_sum(71, r1 + 2, c2 - 1, r2 - 2, c2 - 1) // inner edges
            + get_sum(80, r1 + 2, c1 + 2, r2 - 2, c2 - 2) == 1); // interior
          }
        }
      }
    }
  }
  cout << ans << '\n';
  return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 1 ms 212 KB Output is correct
2 Execution timed out 5063 ms 51900 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 340 KB Output is correct
2 Incorrect 3 ms 340 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 340 KB Output is correct
2 Incorrect 3 ms 340 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 340 KB Output is correct
2 Incorrect 3 ms 340 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 340 KB Output is correct
2 Incorrect 3 ms 340 KB Output isn't correct
3 Halted 0 ms 0 KB -