This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#ifdef tabr
#include "library/debug.cpp"
#else
#define debug(...)
#endif
struct dsu {
    vector<int> p;
    vector<int> sz;
    vector<int> mn;
    vector<int> mx;
    int n;
    dsu(int _n) : n(_n) {
        p = vector<int>(n);
        iota(p.begin(), p.end(), 0);
        sz = vector<int>(n, 1);
        mx = p;
        mn = p;
    }
    inline int get(int x) {
        if (p[x] == x) {
            return x;
        } else {
            return p[x] = get(p[x]);
        }
    }
    inline bool unite(int x, int y) {
        x = get(x);
        y = get(y);
        if (x == y) {
            return false;
        }
        p[x] = y;
        sz[y] += sz[x];
        mn[y] = min(mn[y], mn[x]);
        mx[y] = max(mx[y], mx[x]);
        return true;
    }
    inline bool same(int x, int y) {
        return (get(x) == get(y));
    }
    inline int size(int x) {
        return sz[get(x)];
    }
    inline bool root(int x) {
        return (x == get(x));
    }
};
long long count_rectangles(vector<vector<int>> a) {
    int h = (int) a.size();
    int w = (int) a[0].size();
    long long res = 0;
    map<pair<int, int>, long long> cnt;
    for (int i = 1; i < h - 1; i++) {
        vector<vector<int>> bound(w);
        map<int, vector<int>> v;
        for (int j = 0; j < w; j++) {
            v[a[i][j]].emplace_back(j);
        }
        dsu uf(w);
        for (auto p : v) {
            for (int j : p.second) {
                if (j - 1 >= 0 && a[i][j] >= a[i][j - 1]) {
                    uf.unite(j - 1, j);
                }
                if (j + 1 < w && a[i][j] >= a[i][j + 1]) {
                    uf.unite(j + 1, j);
                }
            }
            set<int> used;
            for (int j : p.second) {
                if (!used.count(uf.get(j)) && uf.mn[uf.get(j)] > 0 && uf.mx[uf.get(j)] < w - 1) {
                    used.emplace(uf.get(j));
                    bound[uf.mx[uf.get(j)]].emplace_back(uf.mn[uf.get(j)]);
                }
            }
        }
        int up_last = 0;
        int down_last = 0;
        map<pair<int, int>, long long> new_cnt;
        for (int j = 1; j < w - 1; j++) {
            if (a[i][j] >= a[i - 1][j]) {
                up_last = j;
            }
            if (a[i][j] >= a[i + 1][j]) {
                down_last = j;
            }
            for (int k : bound[j]) {
                new_cnt[make_pair(k, j)] = cnt[make_pair(k, j)];
                if (up_last < k) {
                    new_cnt[make_pair(k, j)]++;
                }
                if (down_last < k) {
                    res += new_cnt[make_pair(k, j)];
                }
            }
        }
        swap(cnt, new_cnt);
    }
    return res;
}
#ifdef tabr
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    debug(count_rectangles({{4, 8, 7, 5, 6},
                            {7, 4, 10, 3, 5},
                            {9, 7, 20, 14, 2},
                            {9, 14, 7, 3, 6},
                            {5, 7, 5, 2, 7},
                            {4, 5, 13, 5, 6}}));
    return 0;
}
#endif
| # | 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... |