Submission #157343

#TimeUsernameProblemLanguageResultExecution timeMemory
157343qkxwsmRectangles (IOI19_rect)C++14
72 / 100
3547 ms1048580 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; template<class T, class U> void ckmin(T &a, U b) { if (a > b) a = b; } template<class T, class U> void ckmax(T &a, U b) { if (a < b) a = b; } #define y1 qkx #define y2 wsm #define MP make_pair #define PB push_back #define LB lower_bound #define UB upper_bound #define fi first #define se second #define FOR(i, a, b) for (auto i = (a); i < (b); i++) #define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--) #define SZ(x) ((int) (x).size()) #define ALL(x) (x).begin(), (x).end() #define INF 1000000007 #define MAXN 2513 typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef vector<int> vi; typedef vector<ll> vl; typedef vector<pii> vpi; typedef vector<pll> vpl; int N, M; vector<vi> grid; int rt[MAXN][MAXN], dn[MAXN][MAXN], lt[MAXN][MAXN], up[MAXN][MAXN]; vi ev[MAXN][MAXN], eh[MAXN][MAXN]; vi dv[MAXN][MAXN], dh[MAXN][MAXN]; ll ans; ll count_rectangles(vector<vi> a) { N = SZ(a); M = SZ(a[0]); grid = a; //BE SUPER CAREFUL ABOUT EQUALITY CASE. //for each guy, find the next guy right of it that's greater th an it. //ok fix the starting column #. FOR(i, 0, N) { vpi cand; cand.PB({INF, M + 1}); FORD(j, M, 0) { while(cand.back().fi < grid[i][j]) cand.pop_back(); rt[i][j] = cand.back().se; cand.PB({grid[i][j], j}); } cand.clear(); cand.PB({INF, -2}); FOR(j, 0, M) { while(cand.back().fi < grid[i][j]) cand.pop_back(); lt[i][j] = cand.back().se; cand.PB({grid[i][j], j}); } } FOR(i, 0, M) { vpi cand; cand.PB({INF, N + 1}); FORD(j, N, 0) { while(cand.back().fi < grid[j][i]) cand.pop_back(); dn[j][i] = cand.back().se; cand.PB({grid[j][i], j}); } cand.clear(); cand.PB({INF, -2}); FOR(j, 0, N) { while(cand.back().fi < grid[j][i]) cand.pop_back(); up[j][i] = cand.back().se; cand.PB({grid[j][i], j}); } } FOR(i, 0, N) { FOR(j, 0, M) { // cerr << "POS " << i << ' ' << j << endl; int idx = lt[i][j]; // cerr << idx << ' '; if (idx >= 0 & idx != j - 1) { eh[i][idx + 1].PB(j - 1); } idx = rt[i][j]; // cerr << idx << ' '; if (idx < M && idx != j + 1) { eh[i][j + 1].PB(idx - 1); } idx = up[i][j]; // cerr << idx << ' '; if (idx >= 0 && idx != i - 1) { ev[idx + 1][j].PB(i - 1); } idx = dn[i][j]; // cerr << idx << endl; if (idx < N && idx != i + 1) { ev[i + 1][j].PB(idx - 1); } } } FOR(i, 0, N) { FOR(j, 0, M) { sort(ALL(ev[i][j])); ev[i][j].erase(unique(ALL(ev[i][j])), ev[i][j].end()); sort(ALL(eh[i][j])); eh[i][j].erase(unique(ALL(eh[i][j])), eh[i][j].end()); dv[i][j].resize(SZ(ev[i][j])); dh[i][j].resize(SZ(eh[i][j])); // cerr << "EDGES FROM " << i << ',' << j << endl; // cerr << "VERTICAL\n"; // for (int x : ev[i][j]) // { // cerr << x << ' ' << j << endl; // } // cerr << "HORIZONTAL\n"; // for (int y : eh[i][j]) // { // cerr << i << ' ' << y << endl; // } } } FOR(i, 0, N) { FORD(j, M, 0) { int idx = 0; FOR(k, 0, SZ(ev[i][j])) { dv[i][j][k] = j; int x = ev[i][j][k]; while(idx < SZ(ev[i][j + 1]) && ev[i][j + 1][idx] < x) idx++; if (idx >= SZ(ev[i][j + 1]) || ev[i][j + 1][idx] != x) continue; dv[i][j][k] = dv[i][j + 1][idx]; } } } FOR(i, 0, M) { FORD(j, N, 0) { int idx = 0; FOR(k, 0, SZ(eh[j][i])) { dh[j][i][k] = j; int y = eh[j][i][k]; while(idx < SZ(eh[j + 1][i]) && eh[j + 1][i][idx] < y) idx++; if (idx >= SZ(eh[j + 1][i]) || eh[j + 1][i][idx] != y) continue; dh[j][i][k] = dh[j + 1][i][idx]; } } } FOR(i, 1, N - 1) { FOR(j, 1, M - 1) { FOR(k, 0, SZ(ev[i][j])) { int x = ev[i][j][k]; if (x >= N - 1) continue; FOR(m, 0, SZ(eh[i][j])) { int y = eh[i][j][m]; if (y >= M - 1) continue; if (dh[i][j][m] >= x && dv[i][j][k] >= y) { // cout << i << ',' << j << "=>" << x << ',' << y << endl; ans++; } } } } } //for each horizontal segment, see how far up it can go. //for each vertical segment, see how far left it can go //ok lol idk return ans; }

Compilation message (stderr)

rect.cpp: In function 'll count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:96:12: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
    if (idx >= 0 & idx != j - 1)
        ~~~~^~~~
#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...