Submission #656837

#TimeUsernameProblemLanguageResultExecution timeMemory
656837jcelinRectangles (IOI19_rect)C++14
100 / 100
2664 ms695328 KiB
#include "rect.h" #include <bits/stdc++.h> //#include<ext/pb_ds/assoc_container.hpp> //#include<ext/pb_ds/tree_policy.hpp> using namespace std; //using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef unsigned int ui; #define ii pair<int,int> #define pll pair<ll,ll> #define vi vector<int> #define vii vector<ii> #define vll vector<ll> #define vpll vector<pll> #define matrix vector<vi> #define matrixLL vector<vll> #define vs vector<string> #define vui vector<ui> #define msi multiset<int> #define mss multiset<string> #define si set<int> #define ss set<string> #define PB push_back #define PF push_front #define PPB pop_back #define PPF pop_front #define X first #define Y second #define MP make_pair #define FOR(i, a, b) for (int i = int(a); i < int(b); i++) #define REP(i, n) FOR(i, 0, n) #define all(x) (x).begin(), (x).end() const int dx[] = {-1, 1, 0, 0}; const int dy[] = {0, 0, -1, 1}; const int dxx[] = {-1, 1, 0, 0, 1, 1, -1, -1}; const int dyy[] = {0, 0, -1, 1, -1, 1, -1, 1}; const string abc="abcdefghijklmnopqrstuvwxyz"; const string ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const ld pi = 3.14159265; const int mod = 1e9 + 7; const int MOD = 1e9 + 7; const int MAXN = 2510; const int inf = mod; const ll INF = 1e18; const ll zero = ll(0); const int logo = 13; const int off = 1 << logo; const int trsz = off << 1; struct tournament{ int seg[trsz], type; int merge(int a, int b){ if(type == 0) return max(a, b); return min(a, b); } void build(){ for(int i=off - 1; i; i--) seg[i] = merge(seg[i * 2], seg[i * 2 + 1]); } void update(int x, int val){ seg[x + off] = val; } int query(int x, int lo, int hi, int a, int b){ if(lo >= b or hi <= a) return inf * type - 5; if(lo >= a and hi <= b) return seg[x]; int mid = (lo + hi) / 2; return merge(query(x * 2, lo, mid, a, b), query(x * 2 + 1, mid, hi, a, b)); } int query(int l, int r){ int sol = inf * type - 5;; for(l += off, r += off; l<r; l >>= 1, r >>= 1){ if(l & 1) sol = merge(sol, seg[l++]); if(r & 1) sol = merge(sol, seg[--r]); } return sol; } }h1[MAXN], h2[MAXN], h3[MAXN], h4[MAXN]; ii st[MAXN]; // i j 0 - prvi veci nalijevo od (i, j) // i j 1 - prvi veci nadesno od (i, j) // i j 2 - prvi veci gore od (i, j) // i j 3 - prvi veci dolje od (i, j) int bg[MAXN][MAXN][4]; ll count_rectangles(matrix mat){ int n = mat.size(); int m = mat[0].size(); int ind = 0; REP(i, n){ st[0] = {inf, -1}; ind = 0; REP(j, m){ while(st[ind].X < mat[i][j]) ind--; bg[i][j][0] = st[ind].Y; h1[j].update(i, bg[i][j][0]); while(st[ind].X <= mat[i][j]) ind--; bg[i][j][0] = st[ind].Y; ind++; st[ind] = {mat[i][j], j}; } st[0] = {inf, m + 1}; ind = 0; for(int j = m - 1; j >= 0; j--){ while(st[ind].X < mat[i][j]) ind--; bg[i][j][1] = st[ind].Y; h2[j].update(i, bg[i][j][1]); while(st[ind].X <= mat[i][j]) ind--; bg[i][j][1] = st[ind].Y; ind++; st[ind] = {mat[i][j], j}; } } REP(j, m){ st[0] = {inf, -1}; ind = 0; REP(i, n){ while(st[ind].X < mat[i][j]) ind--; bg[i][j][2] = st[ind].Y; h3[i].update(j, bg[i][j][2]); while(st[ind].X <= mat[i][j]) ind--; ind++; st[ind] = {mat[i][j], i}; } st[0] = {inf, n + 1}; ind = 0; for(int i = n - 1; i >= 0; i--){ while(st[ind].X < mat[i][j]) ind--; bg[i][j][3] = st[ind].Y; h4[i].update(j, bg[i][j][3]); while(st[ind].X <= mat[i][j]) ind--; bg[i][j][3] = st[ind].Y; ind++; st[ind] = {mat[i][j], i}; } } /* REP(i, n) REP(j, m){ h1[j].update(i, bg[i][j][0]); h2[j].update(i, bg[i][j][1]); h3[i].update(j, bg[i][j][2]); h4[i].update(j, bg[i][j][3]); } */ REP(i, m) h1[i].type = 0, h2[i].type = 1, h1[i].build(), h2[i].build(); REP(j, n) h3[j].type = 0, h4[j].type = 1, h3[j].build(), h4[j].build(); /* cout << "\n"; REP(i, n){ REP(j, m){ cout << bg[i][j][3] << " "; } cout << "\n"; } cout << "\n"; REP(i, n){ REP(j, m){ cout << bg[i][j][2] << " "; } cout << "\n"; }*/ vll good; REP(i, n){ REP(j, m){ if(i == 0 or j == 0 or i == n - 1 or j == m - 1) continue; if(bg[i][j][0] == -1 or bg[i][j][1] == m + 1) continue; if(bg[i][j][2] == -1 or bg[i][j][3] == n + 1) continue; //if(i != 2 or j != 1) continue; //cout << i << " " << j << "\n"; //REP(k, 4) cout << bg[i][j][k] << " "; //cout << '\n'; ll hash = 0; REP(k, 4) hash *= MAXN, hash += bg[i][j][k]; //lijeve gr. if(bg[i][j][0] < h1[bg[i][j][1]].query(bg[i][j][2] + 1, (bg[i][j][3] - 1) + 1)) continue; //cout << "PR1" << "\n"; //desne if(bg[i][j][1] > h2[bg[i][j][0]].query(bg[i][j][2] + 1, (bg[i][j][3] - 1) + 1)) continue; //cout << "PR2" << "\n"; //gore if(bg[i][j][2] < h3[bg[i][j][3]].query(bg[i][j][0] + 1, (bg[i][j][1] - 1) + 1)) continue; //cout << "PR3" << "\n"; //cout << bg[i][j][3] << " " << h4[bg[i][j][2]].query(1, 0, off, bg[i][j][0] + 1, (bg[i][j][1] - 1) + 1) << "\n"; //dolje if(bg[i][j][3] > h4[bg[i][j][2]].query(bg[i][j][0] + 1, (bg[i][j][1] - 1) + 1)) continue; //cout << "PR4" << "\n"; //cout << "DOBARR " << i << " " << j << "\n"; //REP(k, 4) cout << bg[i][j][k] << " "; //cout << "\n---------------\n"; good.PB(hash); } } if(good.empty()) return 0; sort(all(good)); ll pre = good[0]; int ret = 1; for(auto &x : good) ret += (x != pre), pre = x; return ret; } /* 10 10 1 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 1 1 0 1 1 0 0 1 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 1 0 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 */ /* void solve(){ int n, m; cin >> n >> m; matrix cur; vi s; s.resize(m); REP(i, n){ for(auto &x : s) cin >> x; cur.PB(s); } cout << count_rectangles(cur); } int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int t=1; //cin >> t; while(t--)solve(); return 0; } */
#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...