제출 #540743

#제출 시각아이디문제언어결과실행 시간메모리
540743alextodoranRectangles (IOI19_rect)C++17
72 / 100
3639 ms1048576 KiB
/**
 ____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int NM_MAX = 2500;

short int L[NM_MAX][NM_MAX];
short int R[NM_MAX][NM_MAX];
short int U[NM_MAX][NM_MAX];
short int D[NM_MAX][NM_MAX];

map <short int, short int> DProw[NM_MAX][NM_MAX];
map <short int, short int> DPcol[NM_MAX][NM_MAX];

vector <pair <pair <short int, short int>, pair <short int, short int>>> cand;

ll count_rectangles (vector <vector <int>> h) {
    int n = (int) h.size();
    int m = (int) h[0].size();

    for (int i = 0; i < n; i++) {
        vector <int> st;
        for (int j = 0; j < m; j++) {
            while (st.empty() == false && h[i][st.back()] <= h[i][j]) {
                st.pop_back();
            }
            L[i][j] = (st.empty() == false ? st.back() : -1);
            st.push_back(j);
        }
        st.clear();
        for (int j = m - 1; j >= 0; j--) {
            while (st.empty() == false && h[i][st.back()] <= h[i][j]) {
                st.pop_back();
            }
            R[i][j] = (st.empty() == false ? st.back() : -1);
            st.push_back(j);
        }
    }
    for (int j = 0; j < m; j++) {
        vector <int> st;
        for (int i = 0; i < n; i++) {
            while (st.empty() == false && h[st.back()][j] <= h[i][j]) {
                st.pop_back();
            }
            U[i][j] = (st.empty() == false ? st.back() : -1);
            st.push_back(i);
        }
        st.clear();
        for (int i = n - 1; i >= 0; i--) {
            while (st.empty() == false && h[st.back()][j] <= h[i][j]) {
                st.pop_back();
            }
            D[i][j] = (st.empty() == false ? st.back() : -1);
            st.push_back(i);
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            int i1 = U[i][j], i2 = D[i][j];
            int j1 = L[i][j], j2 = R[i][j];
            if (i1 != -1 && i2 != -1) {
                DProw[i1][j][i2] = 1;
            }
            if (j1 != -1 && j2 != -1) {
                DPcol[i][j1][j2] = 1;
            }
            if (i1 != -1 && j1 != -1 && i2 != -1 && j2 != -1) {
                cand.push_back({{i1, j1}, {i2, j2}});
            }
        }
    }
    sort(cand.begin(), cand.end());
    cand.resize(unique(cand.begin(), cand.end()) - cand.begin());

    for (int i = 0; i < n; i++) {
        for (int j = 1; j < m; j++) {
            for (pair <int, int> _ : DProw[i][j]) {
                int i2 = _.first;
                if (DProw[i][j - 1].count(i2) > 0) {
                    DProw[i][j][i2] = DProw[i][j - 1][i2] + 1;
                }
            }
        }
    }
    for (int j = 0; j < m; j++) {
        for (int i = 1; i < n; i++) {
            for (pair <int, int> _ : DPcol[i][j]) {
                int j2 = _.first;
                if (DPcol[i - 1][j].count(j2) > 0) {
                    DPcol[i][j][j2] = DPcol[i - 1][j][j2] + 1;
                }
            }
        }
    }

    int answer = 0;
    for (pair <pair <int, int>, pair <int, int>> c : cand) {
        int i1, j1; tie(i1, j1) = c.first;
        int i2, j2; tie(i2, j2) = c.second;
        if (DProw[i1][j2 - 1][i2] >= j2 - j1 - 1
         && DPcol[i2 - 1][j1][j2] >= i2 - i1 - 1) {
             answer++;
        }
    }

    return answer;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...