Submission #267124

#TimeUsernameProblemLanguageResultExecution timeMemory
267124dooweyRectangles (IOI19_rect)C++14
50 / 100
5067 ms589192 KiB
#include <bits/stdc++.h> #include "rect.h" using namespace std; typedef long long ll; typedef pair<short, short> pii; #define fi first #define se second #define mp make_pair const int N = 2505; short lef[N][N]; short rig[N][N]; short up[N][N]; short dow[N][N]; vector<pii> rr[N][N]; vector<pii> dd[N][N]; struct segtree{ short n; int mode; vector<short> vals; void init(short sz, short md){ n = sz; mode = md; vals.resize(n * 2); } void upd(short x, short v){ if(mode == 0 && v == -1) v = 5005; x += n; vals[x] = v; x >>= 1; 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 >>= 1; } } short get(int l, int r){ l += n; r += n; short sol = 5005; if(mode == 1) sol = -1; while(l <= r){ if((l & 1)){ if(mode == 0) sol = min(sol, vals[l]); else sol = max(sol, vals[l]); l ++ ; } if(!(r & 1)){ if(mode == 0) sol = min(sol, vals[r]); else sol = max(sol, vals[r]); r -- ; } l >>= 1; r >>= 1; } return sol; } }; segtree L[N], R[N], U[N], D[N]; bool is_valid(short i1, short j1, short i2, short j2){ if(D[i1].get(j1 + 1 ,j2 - 1) < i2) return false; if(U[i2].get(j1 + 1, j2 - 1) > i1) return false; if(R[j1].get(i1 + 1, i2 - 1) < j2) return false; if(L[j2].get(i1 + 1, i2 - 1) > j1) return false; return true; } ll count_rectangles(vector<vector<int>>a) { short n = a.size(); short m = a[0].size(); for(int i = 0 ; i < n; i ++ ){ vector<short> 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<short> 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]); sort(dd[i][j].begin(), dd[i][j].end()); dd[i][j].resize(unique(dd[i][j].begin(), dd[i][j].end()) - dd[i][j].begin()); sort(rr[i][j].begin(), rr[i][j].end()); rr[i][j].resize(unique(rr[i][j].begin(), rr[i][j].end()) - rr[i][j].begin()); } } int answ = 0; 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]){ answ += is_valid(i - 1, j, y.fi, x.se); } } } } 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...