Submission #1028759

#TimeUsernameProblemLanguageResultExecution timeMemory
1028759onbertRectangles (IOI19_rect)C++17
10 / 100
1837 ms803852 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; #define int 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]; } for (int i=0;i<n;i++) { vector<pair<int,int>> cur; for (int j=0;j<m;j++) cur.push_back({a[i][j], j}); sort(cur.rbegin(), cur.rend()); set<int> s; s.insert(-1); s.insert(INF); vector<int> temp; 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 r = *it; it--; int l = *it; if (l!=-1 && r!=INF) { l++, r--; 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++) { vector<pair<int,int>> cur; for (int i=0;i<n;i++) cur.push_back({a[i][j], i}); sort(cur.rbegin(), cur.rend()); set<int> s; s.insert(-1); s.insert(INF); vector<int> temp; 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--; 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(); // if (I==1 && sz>0) cout << l << " " << r << " " << sz << endl; 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; // if (I==1) cout << pos[I][l][r][i].first << " " << pos[I][l][r][i].second << endl; } } } for (int I=0;I<=1;I++) { for (int i=0;i<n;i++) for (int j=0;j<m;j++) { // cout << "test " << I << " " << i << " " << j << endl; for (auto &[l, r, mx]:start[I][i][j]) { // cout << l << " " << r << " " << mx << endl; 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; } } } int ans = 0; 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); sort(start[1][i][j].begin(), start[1][i][j].end(), cmp1); int pt = -1; vector<int> LOG; 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++; update(start[1][i][j][pt].r, 1); LOG.push_back(start[1][i][j][pt].r); } 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:119:25: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<range>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  119 |             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...