이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "rect.h"
#include <stack>
#include <vector>
#include <algorithm>
#include <iostream>
#define pii pair<int, int>
#define ppi pair<pii, int>
#define ppp pair<pii, pii>
#define fst first
#define snd second
#define ll long long
#define vi vector<int>
#define vpi vector<pii>
using namespace std;
const int MX = 2505;
int N, M;
struct BIT
{
int A[MX] = {};
inline void upd(int x, int v)
{
for (; x <= N; x += x & (-x)) A[x] += v;
}
inline int qry(int x)
{
int ret = 0;
for (; x; x -= x & (-x)) ret += A[x];
return ret;
}
inline int query(int L, int R) {return qry(R + 1) - qry(L);}
inline void update(int x, int v) {upd(x + 1, v);}
};
vector<int> Hor[MX * MX / 2];
vector<pii> Ver[MX * MX / 2];
vector<pii> Col[MX];
vector<pii> Ins[MX];
BIT DS[MX];
ll ans = 0;
inline int getIndex(int N, int L, int R)
{
return N * (N + 1) / 2 - (N - L) * (N - L + 1) / 2 + (R - L);
}
ll count_rectangles(vector<vector<int>> a)
{
N = a.size(); M = a.front().size();
if (N < 3 || M < 3) return 0;
for (int i = 1; i + 1 < N; i++)
{
vector<int> S;
for (int j = 0; j < M; j++)
{
while (S.size() && a[i][S.back()] < a[i][j])
{
if (S.back() + 1 < j)
{
//cerr << "ROW " << i << ": " << S.back() + 1 << ", " << j - 1 << "\n";
Hor[getIndex(M, S.back() + 1, j - 1)].push_back(i);
}
S.pop_back();
}
if (S.size() && S.back() + 1 < j)
{
//cerr << "ROW " << i << ": " << S.back() + 1 << ", " << j - 1 << "\n";
Hor[getIndex(M, S.back() + 1, j - 1)].push_back(i);
}
while (S.size() && a[i][S.back()] == a[i][j]) S.pop_back();
S.push_back(j);
}
}
for (int j = 1; j + 1 < M; j++)
{
vector<int> S;
for (int i = 0; i < N; i++)
{
while (S.size() && a[S.back()][j] < a[i][j])
{
if (S.back() + 1 < i)
{
Col[j].push_back({S.back() + 1, i - 1});
//cerr << "COLUMN " << j << ": " << S.back() + 1 << ", " << i - 1 << "\n";
if (Ver[getIndex(N, S.back() + 1, i - 1)].size() && Ver[getIndex(N, S.back() + 1, i - 1)].back().snd == j - 1) Ver[getIndex(N, S.back() + 1, i - 1)].back().snd++;
else Ver[getIndex(N, S.back() + 1, i - 1)].push_back({j, j});
}
S.pop_back();
}
if (S.size() && S.back() + 1 < i)
{
Col[j].push_back({S.back() + 1, i - 1});
//cerr << "COLUMN " << j << ": " << S.back() + 1 << ", " << i - 1 << "\n";
if (Ver[getIndex(N, S.back() + 1, i - 1)].size() && Ver[getIndex(N, S.back() + 1, i - 1)].back().snd == j - 1) Ver[getIndex(N, S.back() + 1, i - 1)].back().snd++;
else Ver[getIndex(N, S.back() + 1, i - 1)].push_back({j, j});
}
while (S.size() && a[S.back()][j] == a[i][j]) S.pop_back();
S.push_back(i);
}
}
for (int i = 1; i + 1 < M; i++)
{
for (const auto &x : Col[i])
{
auto it = prev(upper_bound(Ver[getIndex(N, x.fst, x.snd)].begin(), Ver[getIndex(N, x.fst, x.snd)].end(), make_pair(i + 1, -1)));
//cerr << i << ": " << it -> snd << " - " << x.fst << ", " << x.snd << "\n";
Ins[it -> snd].push_back(x);
}
for (int j = M - 2; j >= i; j--)
{
for (const auto &x : Ins[j]) {DS[x.snd].update(x.fst, 1);}
int L = -MX, pv = -MX;
for (const auto &x : Hor[getIndex(M, i, j)])
{
if (pv + 1 < x) {L = x;}
ans += DS[x].query(L, x);
pv = x;
}
Ins[j].clear();
}
for (const auto &x : Col[i]) {DS[x.snd].update(x.fst, -1);}
}
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... |