이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "rect.h"
#include <bits/stdc++.h>
using namespace std;
vector<pair<int, int>> find_borders(const vector<int> &a){
	int n = (int) a.size();
	stack<int> st;
	vector<int> l(n), r(n);
	for (int i = 0; i < n; i++){
		while (!st.empty() && a[st.top()] < a[i]) st.pop();
		l[i] = (st.empty() ? -1 : st.top());
		st.push(i);
	}
	while (!st.empty()) st.pop();
	for (int i = n - 1; i >= 0; i--){
		while (!st.empty() && a[st.top()] < a[i]) st.pop();
		r[i] = (st.empty() ? n : st.top());
		st.push(i);
	}
	vector<pair<int, int>> ans;
	set<pair<int, int>> s1; // (i, r[i])
	set<pair<int, int>> s2; // (r[i], i)
	for (int j = 0; j < n; j++){
		while (!s2.empty()){
			int i = s2.begin()->second;
			if (r[i] < j){
				s1.erase(make_pair(i, r[i]));
				s2.erase(make_pair(r[i], i));
			} else {
				break;
			}
		}
		assert(s1.size() == s2.size());
		auto it = s1.end();
		while (true){
			if (it == s1.begin()) break;
			it--;
			int i = it->first;
			if (i < l[j]) break;
			if (i + 1 < j) ans.emplace_back(i + 1, j - 1);
		}
		s1.emplace(j, r[j]);
		s2.emplace(r[j], j);
	}
	return ans;
}
const int MaxN = 2502;
vector<int> ind[MaxN][MaxN], val[MaxN][MaxN];
int cnt[MaxN * MaxN];
long long count_rectangles(vector<vector<int>> A) {
	int n = (int) A.size(), m = (int) A[0].size();
	for (int i = 1; i + 1 < n; i++){
		vector<pair<int, int>> f = find_borders(A[i]);
		for (auto [l, r] : f){
			ind[l][r].push_back(i);
		}
	}
	for (int j = 1; j + 1 < m; j++){
		vector<int> col(n);
		for (int i = 0; i < n; i++) col[i] = A[i][j];
		vector<pair<int, int>> f = find_borders(col);
		for (auto [l, r] : f){
			val[r][j].push_back(l * n + r);
		}
	}
	long long ans = 0;
	for (int l = 1; l < m - 1; l++) for (int r = l; r < m - 1; r++){
		int sz = (int) ind[l][r].size();
		for (int ii = 0; ii < sz; ii++){
			int x = ind[l][r][ii];
			if (ii > 0 && ind[l][r][ii - 1] == x - 1) continue;
			vector<int> used_values;
			for (int jj = ii; jj < sz; jj++){
				int y = ind[l][r][jj];
				if (y - x != jj - ii) break;
				for (int j = l; j <= r; j++){
					for (int v : val[y][j]){
						if (v / n < x) continue;
						cnt[v]++;
						if (cnt[v] == r - l + 1) ans++;
						used_values.push_back(v);
					}
				}
			}
			for (int v : used_values){
				cnt[v] = 0;
			}
		}
	}
	return ans;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |