Submission #421215

#TimeUsernameProblemLanguageResultExecution timeMemory
421215MohamedAhmed04Rectangles (IOI19_rect)C++14
100 / 100
4126 ms811704 KiB
#include <bits/stdc++.h> #include "rect.h" //#include "grader.cpp" using namespace std ; const int MAX = 2501 ; vector<int>bit[MAX][MAX] ; vector<int>v2[MAX][MAX] ; int getidx(int i , int j , int x) { int idx = upper_bound(v2[i][j].begin() , v2[i][j].end() , x) - v2[i][j].begin() ; return idx ; } void Add(int i2 , int j2 , int i , int x) { int n = v2[i2][j2].size() ; for(; i <= n ; i += (i & (-i))) bit[i2][j2][i] += x ; } void Insert(int i2 , int j2 , int i) { Add(i2 , j2 , getidx(i2 , j2 , i) , 1) ; } void Erase(int i2 , int j2 , int i) { Add(i2 , j2 , getidx(i2 , j2 , i) , -1) ; } int get(int i2 , int j2 , int i) { int sum = 0 ; for(; i > 0 ; i -= (i & (-i))) sum += bit[i2][j2][i] ; return sum ; } int query(int i2 , int j2 , int i) { return get(i2 , j2 , getidx(i2 , j2 , i)) ; } void init(int i , int j) { int n = v2[i][j].size() ; bit[i][j] = vector<int>(n+1 , 0) ; for(auto &x : v2[i][j]) Insert(i , j , x) ; } vector<int>candi[MAX] ; stack<int>st[MAX] ; vector<bool>mark[MAX] ; int n , m ; int calc(int i , int j , int i2 , int last) { int j2 = j-1 ; i2++ ; if(j2 < 0 || i2 >= i) return 0ll ; return (query(i2 , j2 , last+1) - query(i2 , j2 , j)) ; } vector< vector<int> >a ; vector<int>erased ; stack<int>st2 ; void AddRow(int i) { while(st2.size()) st2.pop() ; for(int j = m-1 ; j >= 0 ; --j) { while(st2.size() && a[i][j] > a[i][st2.top()]) v2[i][j].push_back(st2.top()) , st2.pop() ; if(st2.size()) v2[i][j].push_back(st2.top()) ; while(st2.size() && a[i][st2.top()] == a[i][j]) st2.pop() ; st2.push(j) ; sort(v2[i][j].begin() , v2[i][j].end()) ; init(i , j) ; } if(!i) return ; for(int j = 0 ; j < m ; ++j) { erased.clear() ; for(auto &k : v2[i-1][j]) { if(!binary_search(v2[i][j].begin() , v2[i][j].end() , k)) erased.push_back(k) ; } for(auto &k : erased) { for(int i2 = i-1 ; i2 >= 0 ; --i2) { if(!binary_search(v2[i2][j].begin() , v2[i2][j].end() , k)) break ; Erase(i2 , j , k) ; } } } } long long count_rectangles(std::vector<std::vector<int> > v) { a = v ; n = a.size() , m = a[0].size() ; long long ans = 0 ; for(int i = 0 ; i < n ; ++i) { for(int j = 0 ; j < m ; ++j) { while(st[j].size() && a[i][j] > a[st[j].top()][j]) candi[j].push_back(st[j].top()) , st[j].pop() ; if(st[j].size()) candi[j].push_back(st[j].top()) ; while(st[j].size() && a[st[j].top()][j] == a[i][j]) st[j].pop() ; st[j].push(i) ; sort(candi[j].begin() , candi[j].end()) ; mark[j] = vector<bool>(candi[j].size() , 0) ; } for(int j = 0 ; j < m ; ++j) { for(auto &i2 : candi[j]) { int idx = lower_bound(candi[j].begin() , candi[j].end() , i2) - candi[j].begin() ; if(mark[j][idx]) continue ; int last = j ; for(int k = j ; k < m ; ++k) { if(!binary_search(candi[k].begin() , candi[k].end() , i2)) break ; last = k ; } for(int k = j ; k <= last ; ++k) { ans += calc(i , k , i2 , last) ; if(k != j) { idx = lower_bound(candi[k].begin() , candi[k].end() , i2) - candi[k].begin() ; mark[k][idx] = 1 ; } } } candi[j].clear() , mark[j].clear() ; } AddRow(i) ; } 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...