Submission #1028787

#TimeUsernameProblemLanguageResultExecution timeMemory
1028787onbertRectangles (IOI19_rect)C++17
72 / 100
2646 ms1048576 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; #define ll long long struct range { int l, r, mx; }; bool cmp0(range &a, range &b) {return a.r > b.r;} bool cmp1(range &a, range &b) {return a.mx > b.mx;} const int maxn = 2505, INF = 1e9; int n, m; vector<vector<int>> a; vector<pair<int,int>> pos[2][maxn][maxn]; vector<range> start[2][maxn][maxn]; int fen[maxn]; void update(int id, int val) { while (id<maxn) { fen[id] += val; id += (id & -id); } } int qry(int id) { int val = 0; while (id >= 1) { val += fen[id]; id -= (id & -id); } return val; } long long count_rectangles(vector<vector<int32_t>> A) { n = A.size(), m = A[0].size(); a.resize(n); for (int i=0;i<n;i++) { a[i].resize(m); for (int j=0;j<m;j++) a[i][j] = A[i][j]; } vector<pair<int,int>> cur; vector<int> temp; set<int> s; for (int i=0;i<n;i++) { cur.clear(); for (int j=0;j<m;j++) cur.push_back({a[i][j], j}); sort(cur.rbegin(), cur.rend()); s.clear(); s.insert(-1); s.insert(INF); temp.clear(); for (int j=0;j<m;j++) { auto [val, id] = cur[j]; if (j>0 && val!=cur[j-1].first) { for (int x:temp) s.insert(x); temp.clear(); } auto it = s.upper_bound(id); int l = *prev(it), r = *it; if (l!=-1 && r!=INF) { l++, r--; if (pos[0][l][r].size()==0 || pos[0][l][r].back().first!=i) { pos[0][l][r].push_back({i, -1}); start[0][i][l].push_back({l, r, -1}); } } temp.push_back(id); } } for (int j=0;j<m;j++) { cur.clear(); for (int i=0;i<n;i++) cur.push_back({a[i][j], i}); sort(cur.rbegin(), cur.rend()); s.clear(); s.insert(-1); s.insert(INF); temp.clear(); for (int i=0;i<n;i++) { auto [val, id] = cur[i]; if (i>0 && val!=cur[i-1].first) { for (int x:temp) s.insert(x); temp.clear(); } auto it = s.upper_bound(id); int l = *prev(it), r = *it; if (l!=-1 && r!=INF) { l++, r--; if (pos[1][l][r].size()==0 || pos[1][l][r].back().first!=j) { pos[1][l][r].push_back({j, -1}); start[1][l][j].push_back({l, r, -1}); } } temp.push_back(id); } } for (int I=0;I<=1;I++) { int nn = m; if (I==1) nn = n; for (int l=0;l<nn;l++) for (int r=l;r<nn;r++) { sort(pos[I][l][r].begin(), pos[I][l][r].end()); int sz = pos[I][l][r].size(); for (int i=sz-1;i>=0;i--) { if (i==sz-1 || pos[I][l][r][i+1].first!=pos[I][l][r][i].first+1) pos[I][l][r][i].second = pos[I][l][r][i].first; else pos[I][l][r][i].second = pos[I][l][r][i+1].second; } } } for (int I=0;I<=1;I++) { for (int i=0;i<n;i++) for (int j=0;j<m;j++) { for (auto &[l, r, mx]:start[I][i][j]) { int id = i; if (I==1) id = j; mx = (*lower_bound(pos[I][l][r].begin(), pos[I][l][r].end(), make_pair(id, -INF))).second; } } } ll ans = 0; vector<int> LOG; for (int i=0;i<n;i++) for (int j=0;j<m;j++) { sort(start[0][i][j].begin(), start[0][i][j].end(), cmp0); // start[0][i][j].erase(unique(start[0][i][j].begin(), start[0][i][j].end()), start[0][i][j].end()); sort(start[1][i][j].begin(), start[1][i][j].end(), cmp1); // start[1][i][j].erase(unique(start[1][i][j].begin(), start[1][i][j].end()), start[1][i][j].end()); int pt = -1; LOG.clear(); for (auto [l, r, mx]:start[0][i][j]) { while (pt+1 < start[1][i][j].size() && start[1][i][j][pt+1].mx >= r) { pt++; // if (i==1 && j==2) cout << start[1][i][j][pt].l << " " << start[1][i][j][pt].r << endl; update(start[1][i][j][pt].r, 1); LOG.push_back(start[1][i][j][pt].r); } // if (qry(mx) > 0) { // cout << "ANS " << qry(mx) << endl; // cout << i << " " << j << endl; // cout << l << " " << r << endl; // } ans += qry(mx); } for (int x:LOG) update(x, -1); } return ans; }

Compilation message (stderr)

rect.cpp: In function 'long long int count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:123:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<range>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  123 |             while (pt+1 < start[1][i][j].size() && start[1][i][j][pt+1].mx >= r) {
      |                    ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#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...