Submission #267116

#TimeUsernameProblemLanguageResultExecution timeMemory
267116dooweyRectangles (IOI19_rect)C++14
50 / 100
3469 ms1048580 KiB
#include <bits/stdc++.h>
#include "rect.h"

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

#define fi first
#define se second
#define mp make_pair

const int N = 2505;
int lef[N][N];
int rig[N][N];
int up[N][N];
int dow[N][N];

vector<pii> rr[N][N];
vector<pii> dd[N][N];


struct segtree{
    int n;
    int mode;
    vector<int> vals;
    void init(int sz, int md){
        n = sz;
        mode = md;
        vals.resize(n * 2);
    }
    void upd(int x, int v){
        if(mode == 0 && v == -1)
            v = (int)1e9;
        x += n;
        vals[x] = v;
        x /= 2;
        while(x > 0){
            if(mode == 0) vals[x] = min(vals[x * 2], vals[x * 2 + 1]);
            else vals[x] = max(vals[x * 2], vals[x * 2 + 1]);
            x /= 2;
        }
    }
    int get(int l, int r){
        l += n;
        r += n;
        int sol = (int)1e9;
        if(mode == 1) sol = -1;
        while(l <= r){
            if(l % 2 == 1){
                if(mode == 0) sol = min(sol, vals[l]);
                else sol = max(sol, vals[l]);
                l ++ ;
            }
            if(r % 2 == 0){
                if(mode == 0) sol = min(sol, vals[r]);
                else sol = max(sol, vals[r]);
                r -- ;
            }
            l /= 2;
            r /= 2;
        }
        return sol;
    }
};

segtree L[N], R[N], U[N], D[N];

ll count_rectangles(vector<vector<int>>a) {
	int n = a.size();
	int m = a[0].size();
    for(int i = 0 ; i < n; i ++ ){
        vector<int> mn;
        for(int j = 0 ; j < m ; j ++ ){
            lef[i][j]=-1;
            while(!mn.empty() && a[i][mn.back()] < a[i][j]){
                mn.pop_back();
            }
            if(!mn.empty())
                lef[i][j] = mn.back();
            mn.push_back(j);
        }
        mn.clear();
        for(int j = m - 1; j >= 0 ; j -- ){
            rig[i][j]=-1;
            while(!mn.empty() && a[i][mn.back()] < a[i][j]){
                mn.pop_back();
            }
            if(!mn.empty())
                rig[i][j] = mn.back();
            mn.push_back(j);
        }
        for(int j = 0 ; j < m ; j ++ ){
            if(rig[i][j] != -1 && rig[i][j] > j + 1){
                rr[i][j].push_back(mp(i, rig[i][j]));
            }
            if(lef[i][j] != -1 && lef[i][j] + 1 < j){
                rr[i][lef[i][j]].push_back(mp(i,j));
            }
        }
    }
    for(int j = 0 ; j < m ; j ++ ){
        vector<int> mn;
        for(int i = 0 ; i < n; i ++ ){
            up[i][j]=-1;
            while(!mn.empty() && a[mn.back()][j] < a[i][j]){
                mn.pop_back();
            }
            if(!mn.empty())
                up[i][j] = mn.back();
            mn.push_back(i);
        }
        mn.clear();
        for(int i = n - 1; i >= 0 ; i -- ){
            dow[i][j]=-1;
            while(!mn.empty() && a[mn.back()][j] < a[i][j]){
                mn.pop_back();
            }
            if(!mn.empty())
                dow[i][j] = mn.back();
            mn.push_back(i);
        }
        for(int i = 0 ; i < n; i ++ ){
            if(dow[i][j] != -1 && i + 1 < dow[i][j]){
                dd[i][j].push_back(mp(dow[i][j], j));
            }
            if(up[i][j] != -1 && up[i][j] + 1 < i){
                dd[up[i][j]][j].push_back(mp(i, j));
            }
        }
    }
    for(int i = 0 ; i < m; i ++ ){
        L[i].init(n,1);
        R[i].init(n,0);
        for(int j = 0 ; j < n; j ++ ){
            R[i].upd(j,rig[j][i]);
            L[i].upd(j,lef[j][i]);
        }
    }
    for(int i = 0 ; i < n; i ++ ){
        U[i].init(m,1);
        D[i].init(m,0);
        for(int j = 0 ; j < m ; j ++ ){
            U[i].upd(j, up[i][j]);
            D[i].upd(j, dow[i][j]);
        }
    }
    vector<pair<pii, pii>> cand;
    for(int i = 1 ; i < n; i ++ ){
        for(int j = 0 ; j + 1 < m ; j ++ ){
            for(auto x : rr[i][j]){
                for(auto y : dd[i - 1][j + 1]){
                    cand.push_back({mp(i - 1, j), mp(y.fi, x.se)});
                }
            }
        }
    }
    sort(cand.begin(), cand.end());
    cand.resize(unique(cand.begin(), cand.end()) - cand.begin());
    int i1, j1, i2, j2;
    bool valid;
    int answ = 0;
    for(auto p : cand){
        i1 = p.fi.fi;
        j1 = p.fi.se;
        i2 = p.se.fi;
        j2 = p.se.se;
        valid = true;
        if(D[i1].get(j1 + 1 ,j2 - 1) < i2) valid = false;
        if(U[i2].get(j1 + 1, j2 - 1) > i1) valid = false;
        if(R[j1].get(i1 + 1, i2 - 1) < j2) valid = false;
        if(L[j2].get(i1 + 1, i2 - 1) > j1) valid = false;
        answ += valid;
    }
    return answ;
}
#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...