Submission #199933

#TimeUsernameProblemLanguageResultExecution timeMemory
199933triRectangles (IOI19_rect)C++14
0 / 100
7 ms888 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> // Common file #include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update using namespace std; typedef long long ll; typedef long double ld; typedef pair<int, int> pi; typedef pair<ll, ll> pl; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; using namespace __gnu_pbds; typedef tree< int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; #define pb push_back #define f first #define s second namespace debug { const int DEBUG = true; template<class T1, class T2> void pr(const pair<T1, T2> &x); template<class T, size_t SZ> void pr(const array<T, SZ> &x); template<class T> void pr(const vector<T> &x); template<class T> void pr(const set<T> &x); template<class T1, class T2> void pr(const map<T1, T2> &x); template<class T> void pr(const T &x) { if (DEBUG) cout << x; } template<class T, class... Ts> void pr(const T &first, const Ts &... rest) { pr(first), pr(rest...); } template<class T1, class T2> void pr(const pair<T1, T2> &x) { pr("{", x.f, ", ", x.s, "}"); } template<class T> void prIn(const T &x) { pr("{"); bool fst = 1; for (auto &a : x) { pr(fst ? "" : ", ", a), fst = 0; } pr("}"); } template<class T, size_t SZ> void pr(const array<T, SZ> &x) { prIn(x); } template<class T> void pr(const vector<T> &x) { prIn(x); } template<class T> void pr(const set<T> &x) { prIn(x); } template<class T1, class T2> void pr(const map<T1, T2> &x) { prIn(x); } void ps() { pr("\n"), cout << flush; } template<class Arg, class... Args> void ps(const Arg &first, const Args &... rest) { pr(first, " "); ps(rest...); } } using namespace debug; const int MAXN = 2505; int N, M; ll ans = 0; struct block { int l, r; int len; bool operator<(block o) { if (l != o.l) return l < o.l; if (r != o.r) return r < o.r; return len < o.len; } bool operator<(pi o) { if (l != o.f) return l < o.f; return r < o.s; } bool operator==(pi o) { return l == o.f && r == o.s; } }; bool longestFirst(block a, block b) { if (a.len != b.len) return a.len > b.len; return a < b; } vector<pi> findRanges(vi &a) { vector<pi> ranges; set<int> active; vector<pi> pts; for (int i = 0; i < a.size(); i++) { pts.pb({a[i], i}); } sort(pts.begin(), pts.end()); reverse(pts.begin(), pts.end()); for (pi &x :pts) { int cLoc = x.s; auto it = active.upper_bound(cLoc); if (it != active.end()) { int above = *it; if (cLoc + 1 < above) { ranges.pb({cLoc + 1, above - 1}); } } if (it != active.begin()) { it--; int below = *it; if (below + 1 < cLoc) { ranges.pb({below + 1, cLoc - 1}); } } active.insert(cLoc); } sort(ranges.begin(), ranges.end()); return ranges; } vector<pi> ranges[MAXN]; vector<block> rColumnQ[MAXN]; int mode = 0; vector<block> matchPrev(vector<block> blocks, vector<pi> ranges, int cRow = -1) { vector<block> newBlocks; int nBI = 0; for (pi cR : ranges) { while (nBI < blocks.size() && blocks[nBI] < cR) { if (mode == 0) { block cBlock = blocks[nBI]; // end of cBlock (no longer extended) rColumnQ[cBlock.r].pb({cRow - cBlock.len, cRow - 1, cBlock.r - cBlock.l + 1}); } nBI++; } if (nBI < blocks.size() && blocks[nBI] == cR) { block cBlock = blocks[nBI]; newBlocks.pb({cBlock.l, cBlock.r, cBlock.len + 1}); nBI++; } else { newBlocks.pb({cR.f, cR.s, 1}); } } while (nBI < blocks.size()) { if (mode == 0) { block cBlock = blocks[nBI]; // end of cBlock (no longer extended) rColumnQ[cBlock.r].pb({cRow - cBlock.len, cRow - 1, cBlock.r - cBlock.l + 1}); } nBI++; } return newBlocks; } vi getColumn(vector<vi> &a, int cI) { vi col; for (int i = 0; i < N; i++) { col.pb(a[i][cI]); } return col; } ll count_rectangles(vector<vi> a) { N = a.size(); M = a[0].size(); for (int cR = 1; cR < N; cR++) { ranges[cR] = findRanges(a[cR]); } mode = 0; vector<block> cBlocks; for (int cR = 1; cR <= N; cR++) { // include N to flush all blocks at the end cBlocks = matchPrev(cBlocks, ranges[cR], cR); } cBlocks.clear(); mode = 1; ordered_set osets[MAXN]; for (int cC = 1; cC < N; cC++) { vi cCol = getColumn(a, cC); vector<pi> cRanges = findRanges(cCol); cBlocks = matchPrev(cBlocks, cRanges); sort(cBlocks.begin(), cBlocks.end(), longestFirst); int nBI = 0; for (block cQ : rColumnQ[cC]) { while (nBI < cBlocks.size() && cBlocks[nBI].len >= cQ.len) { block cBlock = cBlocks[nBI]; osets[cBlock.r].insert(cBlock.l); nBI++; } for (int cR = cQ.l; cR <= cQ.r; cR++) { ans += osets[cR].size() - osets[cR].order_of_key(cQ.l); } } sort(cBlocks.begin(), cBlocks.end()); } return ans; }

Compilation message (stderr)

rect.cpp: In function 'std::vector<std::pair<int, int> > findRanges(vi&)':
rect.cpp:124:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < a.size(); i++) {
                     ~~^~~~~~~~~~
rect.cpp: In function 'std::vector<block> matchPrev(std::vector<block>, std::vector<std::pair<int, int> >, int)':
rect.cpp:166:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         while (nBI < blocks.size() && blocks[nBI] < cR) {
                ~~~~^~~~~~~~~~~~~~~
rect.cpp:176:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if (nBI < blocks.size() && blocks[nBI] == cR) {
             ~~~~^~~~~~~~~~~~~~~
rect.cpp:187:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     while (nBI < blocks.size()) {
            ~~~~^~~~~~~~~~~~~~~
rect.cpp: In function 'll count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:237:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while (nBI < cBlocks.size() && cBlocks[nBI].len >= cQ.len) {
                    ~~~~^~~~~~~~~~~~~~~~
#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...