Submission #439396

#TimeUsernameProblemLanguageResultExecution timeMemory
439396SortingRectangles (IOI19_rect)C++17
0 / 100
13 ms20836 KiB
#include "rect.h" #include <bits/stdc++.h> #pragma GCC optimize("O3") using namespace std; typedef long long ll; const int N = 2500 + 3; vector<vector<int>> a; int n, m; short u[N][N], d[N][N], l[N][N], r[N][N]; struct n_Min_Segment_Tree{ static constexpr short DEFAULT_VALUE = SHRT_MAX; short t[4 * N]; int merge(short l, short r){ return (l < r) ? l : r; } void init(short arr[], int i = 0, int l = 0, int r = n - 1){ if(l == r){ t[i] = arr[l]; return; } int mid = (l + r) >> 1; init(arr, 2 * i + 1, l, mid); init(arr, 2 * i + 2, mid + 1, r); t[i] = merge(t[2 * i + 1], t[2 * i + 2]); } int query(int sl, int sr, int i = 0, int l = 0, int r = n - 1){ if(sr < l || r < sl) return DEFAULT_VALUE; if(sl <= l && r <= sr) return t[i]; int mid = (l + r) >> 1; return merge(query(sl, sr, 2 * i + 1, l, mid), query(sl, sr, 2 * i + 2, mid + 1, r)); } }; struct m_Min_Segment_Tree{ static constexpr short DEFAULT_VALUE = SHRT_MAX; short t[4 * N]; int merge(short l, short r){ return (l < r) ? l : r; } void init(short arr[], int i = 0, int l = 0, int r = m - 1){ if(l == r){ t[i] = arr[l]; return; } int mid = (l + r) >> 1; init(arr, 2 * i + 1, l, mid); init(arr, 2 * i + 2, mid + 1, r); t[i] = merge(t[2 * i + 1], t[2 * i + 2]); } int query(int sl, int sr, int i = 0, int l = 0, int r = m - 1){ if(sr < l || r < sl) return DEFAULT_VALUE; if(sl <= l && r <= sr) return t[i]; int mid = (l + r) >> 1; return merge(query(sl, sr, 2 * i + 1, l, mid), query(sl, sr, 2 * i + 2, mid + 1, r)); } }; struct m_Max_Segment_Tree{ static constexpr short DEFAULT_VALUE = SHRT_MIN; short t[4 * N]; int merge(short l, short r){ return (l > r) ? l : r; } void init(short arr[], int i = 0, int l = 0, int r = m - 1){ if(l == r){ t[i] = arr[l]; return; } int mid = (l + r) >> 1; init(arr, 2 * i + 1, l, mid); init(arr, 2 * i + 2, mid + 1, r); t[i] = merge(t[2 * i + 1], t[2 * i + 2]); } int query(int sl, int sr, int i = 0, int l = 0, int r = m - 1){ if(sr < l || r < sl) return DEFAULT_VALUE; if(sl <= l && r <= sr) return t[i]; int mid = (l + r) >> 1; return merge(query(sl, sr, 2 * i + 1, l, mid), query(sl, sr, 2 * i + 2, mid + 1, r)); } }; struct n_Max_Segment_Tree{ static constexpr short DEFAULT_VALUE = SHRT_MIN; short t[4 * N]; int merge(short l, short r){ return (l > r) ? l : r; } void init(short arr[], int i = 0, int l = 0, int r = n - 1){ if(l == r){ t[i] = arr[l]; return; } int mid = (l + r) >> 1; init(arr, 2 * i + 1, l, mid); init(arr, 2 * i + 2, mid + 1, r); t[i] = merge(t[2 * i + 1], t[2 * i + 2]); } int query(int sl, int sr, int i = 0, int l = 0, int r = n - 1){ if(sr < l || r < sl) return DEFAULT_VALUE; if(sl <= l && r <= sr) return t[i]; int mid = (l + r) >> 1; return merge(query(sl, sr, 2 * i + 1, l, mid), query(sl, sr, 2 * i + 2, mid + 1, r)); } }; m_Min_Segment_Tree u_st[N]; n_Min_Segment_Tree l_st[N]; m_Max_Segment_Tree d_st[N]; n_Max_Segment_Tree r_st[N]; void init(){ stack<int> st; for(int j = 0; j < m; ++j){ for(int i = 0; i < n; ++i){ while(!st.empty() && a[i][j] > a[st.top()][j]){ d[st.top()][j] = i; st.pop(); } st.push(i); } while(!st.empty()){ d[st.top()][j] = n; st.pop(); } for(int i = n - 1; i >= 0; --i){ while(!st.empty() && a[i][j] > a[st.top()][j]){ u[st.top()][j] = i; st.pop(); } st.push(i); } while(!st.empty()){ u[st.top()][j] = -1; st.pop(); } } for(int i = 0; i < n; ++i){ for(int j = 0; j < m; ++j){ while(!st.empty() && a[i][j] > a[i][st.top()]){ r[i][st.top()] = j; st.pop(); } st.push(j); } while(!st.empty()){ r[i][st.top()] = m; st.pop(); } for(int j = m - 1; j >= 0; --j){ while(!st.empty() && a[i][j] > a[i][st.top()]){ l[i][st.top()] = j; st.pop(); } st.push(j); } while(!st.empty()){ l[i][st.top()] = -1; st.pop(); } } } bool check(int x1, int y1, int x2, int y2){ return u_st[x2 + 1].query(y1, y2) <= x1 - 1 && d_st[x1 - 1].query(y1, y2) >= x2 + 1 && l_st[y2 + 1].query(x1, x2) <= y1 - 1 && r_st[y1 - 1].query(x1, x2) >= y2 + 1; } long long count_rectangles(vector<vector<int>> _a) { swap(a, _a); n = a.size(), m = a[0].size(); init(); for(int i = 0; i < n; ++i){ u_st[i].init(u[i]); d_st[i].init(d[i]); } static short tmp[N]; for(int j = 0; j < m; ++j){ for(int i = 0; i < n; ++i) tmp[i] = r[i][j]; r_st[j].init(tmp); for(int i = 0; i < n; ++i) tmp[i] = l[i][j]; l_st[j].init(tmp); } ll ans = 0; vector<array<int, 4>> v; for(int x = 1; x < n - 1; ++x) for(int y = 1; y < m - 1; ++y) v.push_back({u[x][y] + 1, l[x][y] + 1, d[x][y] - 1, r[x][y] - 1}); sort(v.begin(), v.end()); v.resize(unique(v.begin(), v.end()) - v.begin()); for(auto [x1, y1, x2, y2]: v){ if(x1 <= 0 || y1 <= 0 || x2 >= n - 1 || y2 >= m - 1) continue; //cout << x1 << " " << y1 << " " << x2 << " " << y2 << endl; ans += check(x1, y1, x2, y2); } return ans; }
#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...