Submission #824750

#TimeUsernameProblemLanguageResultExecution timeMemory
824750tomrukRectangles (IOI19_rect)C++17
100 / 100
2317 ms805412 KiB
#include "rect.h" #include <bits/stdc++.h> #define N 2505 using namespace std; struct BIT2D{ vector<vector<int>> bit; int n; BIT2D(){ n = N; bit.assign(N,vector<int>(N,0)); } void upd(int x,int y,int val){ for(;x < n;x += x & -x){ for(int tmp = y;tmp < n;tmp += tmp & -tmp){ bit[x][tmp] += val; } } } int get(int x,int y){ int ret = 0; for(;x > 0;x -= x & -x){ for(int tmp = y;tmp > 0;tmp -= tmp & -tmp){ ret += bit[x][tmp]; } } return ret; } }; vector<pair<int,int>> dwn[N][N]; vector<pair<int,int>> rght[N][N]; long long count_rectangles(vector<vector<int>> a){ long long ans = 0; int n = a.size(); int m = a[0].size(); for(int i = m-1;i>=0;i--){ vector<int> nxt(n + 5,n); stack<int> st; st.push(n-1); for(int j = n-2;j>=0;j--){ while(st.size() && a[st.top()][i] <= a[j][i]) st.pop(); if(st.size()) nxt[j] = st.top(); st.push(j); if(a[j][i] <= a[j+1][i]) continue; for(int c = nxt[j + 1];c < n;c = nxt[c]){ auto x = lower_bound(rght[j][i+1].begin(),rght[j][i+1].end(),make_pair(c,0)); rght[j][i].push_back({c,1}); if(x != rght[j][i+1].end() && x->first == c){ rght[j][i].back().second += x->second; } if(a[j][i] <= a[c][i]) break; } } } int cnt = 0; BIT2D t; for(int i = n-1;i>0;i--){ vector<int> nxt(m + 5,m); stack<int> st; st.push(m-1); for(int j = m-2;j>=0;j--){ while(st.size() && a[i][st.top()] <= a[i][j]) st.pop(); if(st.size()) nxt[j] = st.top(); st.push(j); if(a[i][j] <= a[i][j+1]) continue; // cout << "HEY" << ' ' << i << ' ' << j << endl; // cout << "ASDASD" << ans << endl; for(auto u:rght[i-1][j+1]){ t.upd(u.first + 1,m-(u.second + j + 1) + 1,1); // cout << u.first + 1 << ' ' << m-(u.second + j + 1) + 1 << endl; } // cout << "HEY" << ' ' << i << ' ' << j << endl; for(int c = nxt[j + 1];c < m;c = nxt[c]){ auto x = lower_bound(dwn[i+1][j].begin(),dwn[i+1][j].end(),make_pair(c,0)); dwn[i][j].push_back({c,1}); if(x != dwn[i+1][j].end() && x->first == c){ dwn[i][j].back().second += x->second; } // cout << i + dwn[i][j].back().second + 1 << endl; // cout << c << endl; ans += t.get(i + dwn[i][j].back().second + 1,m - c + 1); // cout << i + dwn[i][j].back().second + 1 << ' ' << m - c + 1 << endl; // for(int d = i + 1;d <= i + dwn[i][j][c];d++){ // ans += (j + 1 + rght[i-1][j+1][d]) >= c; // } if(a[i][j] <= a[i][c]) break; } for(auto u:rght[i-1][j+1]){ t.upd(u.first + 1,m-(u.second + j + 1) + 1,-1); } // cout << "ASDASD" << ans << endl; } } assert(cnt <= n * m); return ans; }
#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...