Submission #1256184

#TimeUsernameProblemLanguageResultExecution timeMemory
1256184biankRectangles (IOI19_rect)C++20
100 / 100
3800 ms606728 KiB
#include <bits/stdc++.h>

using namespace std;

#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define forn(i, n) forsn(i, 0, n)
#define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--)
#define dforn(i, n) dforsn(i, 0, n)

#define sz(x) int(x.size())
#define all(x) begin(x), end(x)

using ii = pair<int, int>;
using vi = vector<int>;
using ll = long long;
using vll = vector<ll>;

#define fst first
#define snd second

#define pb push_back
#define eb emplace_back

const int INF = 1e9 + 20;

struct SegTree {
    int n;
    vi st;
    SegTree() {}
    SegTree(vi &a) : n(sz(a)), st(2 * n) {
        forn(i, n) st[i + n] = a[i];
        dforsn(i, 1, n) st[i] = max(st[2 * i], st[2 * i + 1]);
    }
    int query(int l, int r) { //[l, r)
        int ret = -INF;
        for (l += n, r += n; l < r; l /= 2, r /= 2) {
            if (l & 1) ret = max(ret, st[l++]);
            if (r & 1) ret = max(st[--r], ret);
        }
        return ret;
    }
};

ll count_rectangles(vector<vi> a) {
    int n = sz(a), m = sz(a[0]);
    vector<vi> l(n, vi(m)), r(n, vi(m));
    vector<vi> d(n, vi(m)), u(n, vi(m));
    forn(i, n) forn(j, m) {
        int k = j - 1;
        while (k >= 0 && a[i][k] < a[i][j]) k = l[i][k];
        l[i][j] = k;
    }
    forn(i, n) dforn(j, m) {
        int k = j + 1;
        while (k < m && a[i][k] < a[i][j]) k = r[i][k];
        r[i][j] = k;
    }
    forn(i, m) forn(j, n) {
        int k = j - 1;
        while (k >= 0 && a[k][i] < a[j][i]) k = u[k][i];
        u[j][i] = k;
    }
    forn(i, m) dforn(j, n) {
        int k = j + 1;
        while (k < n && a[k][i] < a[j][i]) k = d[k][i];
        d[j][i] = k;
    }
    vector<SegTree> minR(m), maxL(m);
    forn(j, m) {
        vi v(n);
        forn(i, n) v[i] = -r[i][j];
        minR[j] = SegTree(v);
    }
    forn(j, m) {
        vi v(n);
        forn(i, n) v[i] = l[i][j];
        maxL[j] = SegTree(v);
    }
    vector<SegTree> minD(n), maxU(n);
    forn(i, n) {
        vi v(m);
        forn(j, m) v[j] = -d[i][j];
        minD[i] = SegTree(v);
    }
    forn(i, n) {
        vi v(m);
        forn(j, m) v[j] = u[i][j];
        maxU[i] = SegTree(v);
    }
    vector<tuple<int, int, int, int>> ret;
    auto check = [&](int i1, int i2, int j1, int j2) {
        if (i1 < 0 || i2 >= n || j1 < 0 || j2 >= m) return;
        if (i2 - i1 < 2 || j2 - j1 < 2) return;
        if (-minR[j1].query(i1 + 1, i2) < j2) return;
        if (maxL[j2].query(i1 + 1, i2) > j1) return;
        if (-minD[i1].query(j1 + 1, j2) < i2) return;
        if (maxU[i2].query(j1 + 1, j2) > i1) return;
        ret.eb(i1, i2, j1, j2);
    };
    forsn(i, 1, n - 1) forsn(j, 1, m - 1) {
        check(u[i + 1][j], i + 1, j - 1, r[i][j - 1]);
        check(u[i + 1][j], i + 1, l[i][j + 1], j + 1);
        check(i - 1, d[i - 1][j], l[i][j + 1], j + 1);
        check(i - 1, d[i - 1][j], j - 1, r[i][j - 1]);
        check(i - 1, d[i - 1][j], j - 1, r[d[i - 1][j] - 1][j - 1]);
        check(i - 1, d[i - 1][j], l[d[i - 1][j] - 1][j + 1], j + 1);
    }
    sort(all(ret));
    return unique(all(ret)) - begin(ret);
}
#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...