Submission #1008611

#TimeUsernameProblemLanguageResultExecution timeMemory
1008611PagodePaivaRectangles (IOI19_rect)C++17
72 / 100
5068 ms495832 KiB
#include "rect.h" #include <bits/stdc++.h> #pragma GCC optimize("Ofast") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #define int int16_t using namespace std; const int N = 2510; const int inf = N; int32_t v[N][N]; int p1[N][N]; int p2[N][N]; int p3[N][N]; int p4[N][N]; struct Segtree{ int tree[4*N]; int join(int a, int b){ return min(a, b); } void build(int node, int l, int r){ if(l == r){ tree[node] = inf; return; } int mid = (l+r)/2; build(2*node, l, mid); build(2*node+1, mid+1, r); tree[node] = join(tree[2*node], tree[2*node+1]); return; } void update(int node, int l, int r, int pos, int val){ if(l == r){ tree[node] = val; return; } int mid = (l+r)/2; if(l <= pos and pos <= mid) update(2*node, l, mid, pos, val); else update(2*node+1, mid+1, r, pos, val); tree[node] = join(tree[2*node], tree[2*node+1]); return; } int query(int node, int l, int r, int tl, int tr){ if(l <= tl and tr <= r) return tree[node]; if(l > tr or tl > r) return inf; int mid = (tl+tr)/2; return join(query(2*node, l, r, tl, mid), query(2*node+1, l, r, mid+1, tr)); } } seg1[N], seg3[N]; struct Segtree2{ int tree[4*N]; int join(int a, int b){ return max(a, b); } void build(int node, int l, int r){ if(l == r){ tree[node] = -1; return; } int mid = (l+r)/2; build(2*node, l, mid); build(2*node+1, mid+1, r); tree[node] = join(tree[2*node], tree[2*node+1]); return; } void update(int node, int l, int r, int pos, int val){ if(l == r){ tree[node] = val; return; } int mid = (l+r)/2; if(l <= pos and pos <= mid) update(2*node, l, mid, pos, val); else update(2*node+1, mid+1, r, pos, val); tree[node] = join(tree[2*node], tree[2*node+1]); return; } int query(int node, int l, int r, int tl, int tr){ if(l <= tl and tr <= r) return tree[node]; if(l > tr or tl > r) return -1; int mid = (tl+tr)/2; return join(query(2*node, l, r, tl, mid), query(2*node+1, l, r, mid+1, tr)); } } seg2[N], seg4[N]; set <array <int, 4>> s; int n, m; bool check(int r1, int c1, int r2, int c2){ if(r1 == 0 or r2 == n+1 or r2-r1 <= 1) return false; if(c1 == 0 or c2 == m+1 or c2-c1 <= 1) return false; if(r1+1 > r2-1 or c1+1 > c2-1) return false; if(c1 <= 0 or c1 > m or c2 <= 0 or c2 > m or r1 <= 0 or r1 > n or r2 <= 0 or r2 > n) return false; int x1 = seg1[c1].query(1,r1+1, r2-1, 1, n); if(c1+1 <= x1 and x1 <= c2-1) return false; x1 = seg2[c2].query(1, r1+1, r2-1, 1, n); if(c1 < x1 and x1 < c2) return false; int x2 = seg3[r1].query(1, c1+1, c2-1, 1, m); if(r1 < x2 and x2 < r2) return false; x2 = seg4[r2].query(1, c1+1, c2-1, 1, m); if(r1 < x2 and x2 < r2) return false; if(s.find({r1, c1, r2, c2}) != s.end()) return false; s.insert({r1, c1, r2, c2}); return true; } long long count_rectangles(std::vector<std::vector<int32_t> > a) { n = a.size(), m = a[0].size(); s.clear(); for(int i = 1;i <= n;i++){ for(int j = 1;j <= m;j++){ v[i][j] = a[i-1][j-1]; } } for(int i = 1;i <= n;i++){ stack <int> s; for(int j = 1;j <= m;j++){ if(s.empty()) s.push(j); else{ while(!s.empty()){ int t = s.top(); if(v[i][j] >= v[i][t]){ p1[i][t] = j; s.pop(); } else{ break; } } s.push(j); } } while(!s.empty()){ int t = s.top(); p1[i][t] = m+1; s.pop(); } } for(int i = 1;i <= n;i++){ stack <int> s; for(int j = m;j > 0;j--){ if(s.empty()) s.push(j); else{ while(!s.empty()){ int t = s.top(); if(v[i][j] >= v[i][t]){ p2[i][t] = j; s.pop(); } else{ break; } } s.push(j); } } while(!s.empty()){ int t = s.top(); p2[i][t] = 0; s.pop(); } } for(int j = 1;j <= m;j++){ stack <int> s; for(int i = 1;i <= n;i++){ if(s.empty()) s.push(i); else{ while(!s.empty()){ int t = s.top(); if(v[i][j] >= v[t][j]){ p3[t][j] = i; s.pop(); } else{ break; } } s.push(i); } } while(!s.empty()){ int t = s.top(); p3[t][j] = n+1; s.pop(); } } for(int j = 1;j <= m;j++){ stack <int> s; for(int i = n;i > 0;i--){ if(s.empty()) s.push(i); else{ while(!s.empty()){ int t = s.top(); if(v[i][j] >= v[t][j]){ p4[t][j] = i; s.pop(); } else{ break; } } s.push(i); } } while(!s.empty()){ int t = s.top(); p4[t][j] = 0; s.pop(); } } for(int i = 1;i <= m;i++){ seg1[i].build(1, 1, n); seg2[i].build(1, 1, n); } for(int i = 1;i <= n;i++){ seg3[i].build(1, 1, m); seg4[i].build(1, 1, m); } for(int i = 1;i <= n;i++){ for(int j = 1;j <= m;j++){ seg1[j].update(1, 1, n, i, p1[i][j]); seg2[j].update(1, 1, n, i, p2[i][j]); seg3[i].update(1, 1, m, j, p3[i][j]); seg4[i].update(1, 1, m, j, p4[i][j]); } } for(int r1 = 1;r1 < n;r1++){ for(int c1 = 1;c1 < m;c1++){ int r2 = p3[r1][c1+1]; int c2 = (1 <= r1+1 and r1+1 <= r2-1 and r2-1 <= n ? seg1[c1].query(1, r1+1, r2-1, 1, n) : -1); check(r1, c1, r2, c2); c2 = p1[r1+1][c1]; r2 = (1 <= c1+1 and c1+1 <= c2-1 and c2-1 <= m ? seg3[r1].query(1, c1+1, c2-1, 1, m) : -1); check(r1, c1, r2, c2); } } for(int r1 = 1;r1 < n;r1++){ for(int c2 = m;c2 > 1;c2--){ int c1 = p2[r1+1][c2]; int r2 = (1 <= c1+1 and c1+1 <= c2-1 and c2-1 <= m ? seg3[r1].query(1, c1+1, c2-1, 1, m) : -1); check(r1, c1, r2, c2); r2 = p3[r1][c2-1]; c1 = (1 <= r1+1 and r1+1 <= r2-1 and r2-1 <= n ? seg2[c2].query(1, r1+1, r2-1, 1, n) : -1); check(r1, c1, r2, c2); } } for(int r2 = n;r2 > 1;r2--){ for(int c1 = 1;c1 < m;c1++){ int r1 = p4[r2][c1+1]; int c2 = (1 <= r1+1 and r1+1 <= r2-1 and r2-1 <= n ? seg1[c1].query(1, r1+1, r2-1, 1, n) : -1); check(r1, c1, r2, c2); c2 = p1[r2-1][c1]; r1 = (1 <= c1+1 and c1+1 <= c2-1 and c2-1 <= m ? seg4[r2].query(1, c1+1, c2-1, 1, m) : -1); check(r1, c1, r2, c2); /* int c2 = p1[r2-1][c1]; int r1 = p4[r2][c1+1]; check(r1, c1, r2, c2); */ } } for(int r2 = n;r2 > 1;r2--){ for(int c2 = m;c2 > 1;c2--){ int c1 = p2[r2-1][c2]; int r1 = (1 <= c1+1 and c1+1 <= c2-1 and c2-1 <= m ? seg4[r2].query(1, c1+1, c2-1, 1, m) : -1); check(r1, c1, r2, c2); r1 = p4[r2][c2-1]; c1 = (1 <= r1+1 and r1+1 <= r2-1 and r2-1 <= n ? seg2[c2].query(1, r1+1, r2-1, 1, n) : -1); check(r1, c1, r2, c2); /* int c1 = p2[r2-1][c2]; int r1 = p4[r2][c2-1]; check(r1, c1, r2, c2); */ } } return s.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...