제출 #624540

#제출 시각아이디문제언어결과실행 시간메모리
624540wiwihoRectangles (IOI19_rect)C++14
10 / 100
543 ms501160 KiB
#include "rect.h"

#include <bits/stdc++.h>
#include <bits/extc++.h>

#define StarBurstStream ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define iter(a) a.begin(), a.end()
#define riter(a) a.rbegin(), a.rend()
#define lsort(a) sort(iter(a))
#define gsort(a) sort(riter(a))
#define pb(a) push_back(a)
#define eb(a) emplace_back(a)
#define pf(a) push_front(a)
#define ef(a) emplace_front(a)
#define pob pop_back()
#define pof pop_front()
#define mp(a, b) make_pair(a, b)
#define F first
#define S second
#define mt make_tuple
#define gt(t, i) get<i>(t)
#define tomax(a, b) ((a) = max((a), (b)))
#define tomin(a, b) ((a) = min((a), (b)))
#define topos(a) ((a) = (((a) % MOD + MOD) % MOD))
#define uni(a) a.resize(unique(iter(a)) - a.begin())
#define printv(a, b) {bool pvaspace=false; \
for(auto pva : a){ \
    if(pvaspace) b << " "; pvaspace=true;\
    b << pva;\
}\
b << "\n";}

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>;

const ll MOD = 1000000007;
const ll MAX = 2147483647;

template<typename A, typename B>
ostream& operator<<(ostream& o, pair<A, B> p){
    return o << '(' << p.F << ',' << p.S << ')';
}

ll ifloor(ll a, ll b){
    if(b < 0) a *= -1, b *= -1;
    if(a < 0) return (a - b + 1) / b;
    else return a / b;
}

ll iceil(ll a, ll b){
    if(b < 0) a *= -1, b *= -1;
    if(a > 0) return (a + b - 1) / b;
    else return a / b;
}

ll count_rectangles(vector<vector<int>> A){
    int n = A.size();
    int m = A[0].size();
    
    vector<vector<int>> L(n, vector<int>(m, -1));
    vector<vector<int>> R(n, vector<int>(m, -1));
    vector<vector<int>> U(n, vector<int>(m, -1));
    vector<vector<int>> D(n, vector<int>(m, -1));

    for(int i = 0; i < n; i++){
        vector<int> v;
        for(int j = 0; j < m; j++){
            while(!v.empty() && A[i][v.back()] < A[i][j]){
                R[i][v.back()] = j;
                v.pob;
            }
            if(v.empty() || A[i][v.back()] == A[i][j]){
                v.eb(j);
                continue;
            }
            L[i][j] = v.back();
            v.eb(j);
        }
    }
    for(int i = 0; i < m; i++){
        vector<int> v;
        for(int j = 0; j < n; j++){
            while(!v.empty() && A[v.back()][i] < A[j][i]){
                D[v.back()][i] = j;
                v.pob;
            }
            if(v.empty() || A[v.back()][i] == A[j][i]){
                v.eb(j);
                continue;
            }
            U[j][i] = v.back();
            v.eb(j);
        }
    }

    vector<vector<vector<pii>>> row(n, vector<vector<pii>>(m));
    vector<vector<vector<pii>>> col(n, vector<vector<pii>>(m));

    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(L[i][j] == -1 || R[i][j] == -1 || U[i][j] == -1 || D[i][j] == -1) continue;
            row[i][L[i][j] + 1].eb(mp(R[i][j] - 1, j));
            col[U[i][j] + 1][j].eb(mp(D[i][j] - 1, i));
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            lsort(row[i][j]);
            lsort(col[i][j]);
        }
    }

    auto getrow = [&](int i, int l, int r){
        //cerr << "getrow " << i << " " << l << " " << r << " : ";
        //printv(row[i][l], cerr);
        auto it = lower_bound(iter(row[i][l]), mp(r, 0));
        if(it == row[i][l].end() || it->F != r) return -1;
        return it->S;
    };
    auto getcol = [&](int i, int l, int r){
        auto it = lower_bound(iter(col[l][i]), mp(r, 0));
        if(it == col[l][i].end() || it->F != r) return -1;
        return it->S;
    };

    vector<vector<int>> rc(n, vector<int>(m, -1));
    vector<vector<int>> cc(n, vector<int>(m, -1));
    for(int i = n - 1; i >= 0; i--){
        for(int j = m - 1; j >= 0; j--){
            if(L[i][j] == -1 || R[i][j] == -1 || U[i][j] == -1 || D[i][j] == -1) continue;
            int id = i == n - 1 ? -1 : getrow(i + 1, L[i][j] + 1, R[i][j] - 1);
            if(id == -1) rc[i][j] = i;
            else rc[i][j] = rc[i + 1][id];
        }
    }
    for(int j = m - 1; j >= 0; j--){
        for(int i = n - 1; i >= 0; i--){
            if(L[i][j] == -1 || R[i][j] == -1 || U[i][j] == -1 || D[i][j] == -1) continue;
            int id = j == m - 1 ? -1 : getcol(j + 1, U[i][j] + 1, D[i][j] - 1);
            if(id == -1) cc[i][j] = j;
            else cc[i][j] = cc[id][j + 1];
        }
    }

    vector<pair<pii, pii>> ans;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(L[i][j] == -1 || R[i][j] == -1 || U[i][j] == -1 || D[i][j] == -1) continue;
            /*//cerr << "test " << i << " " << j << " " << L[i][j] << " " << R[i][j] << " " << U[i][j] << " " << D[i][j] << "\n";
            int idr = getrow(U[i][j] + 1, L[i][j] + 1, R[i][j] - 1);
            int idc = getcol(L[i][j] + 1, U[i][j] + 1, D[i][j] - 1);
            //cerr << idr << " " << idc << "\n";
            if(idr == -1 || idc == -1) continue;
            if(rc[U[i][j] + 1][idr] < D[i][j] - 1) continue;
            if(cc[idc][L[i][j] + 1] < R[i][j] - 1) continue;*/
            bool ok = true;
            //cerr << "test " << i << " " << j << "\n";
            for(int x = U[i][j] + 1; x < D[i][j]; x++){
                int mx = -1, mxp = -1;
                for(int y = L[i][j] + 1; y < R[i][j]; y++){
                    if(A[x][y] > mx) mx = A[x][y], mxp = y;
                }
                if(L[x][mxp] != L[i][j] || R[x][mxp] != R[i][j]) ok = false;
                else{
                    //cerr << "owo " << x << " " << mxp << "\n";
                    assert(getrow(x, L[i][j] + 1, R[i][j] - 1) != -1);
                }
            }
            for(int y = L[i][j] + 1; y < R[i][j]; y++){
                int mx = -1, mxp = -1;
                for(int x = U[i][j] + 1; x < D[i][j]; x++){
                    if(A[x][y] > mx) mx = A[x][y], mxp = x;
                }
                if(U[mxp][y] != U[i][j] || D[mxp][y] != D[i][j]) ok = false;
                else assert(getcol(y, U[i][j] + 1, D[i][j] - 1) != -1);
            }
            if(!ok) continue;
            ans.eb(mp(mp(L[i][j] + 1, R[i][j] - 1), mp(U[i][j] + 1, D[i][j] - 1)));
        }
    }
    lsort(ans);
    uni(ans);

	return ans.size();
}
#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...