Submission #293318

#TimeUsernameProblemLanguageResultExecution timeMemory
293318rqiRectangles (IOI19_rect)C++14
100 / 100
3740 ms386076 KiB
#include "rect.h" #include <bits/stdc++.h> using namespace std; #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; template<class K,class V> using ht = gp_hash_table< K, null_type, hash<K>, equal_to<K>, direct_mask_range_hashing<>, linear_probe_fn<>, hash_standard_resize_policy< hash_exponential_size_policy<>, hash_load_check_resize_trigger<>, true > >; typedef long long ll; typedef pair<int, int> pi; typedef vector<int> vi; typedef vector<pi> vpi; const int MOD = 1000000007; #define ins insert #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define all(x) begin(x), end(x) #define bk back() const int mx = 2505; int n, m; ht<int, null_type> ints2[mx]; vector<pair<int, pi>> queries[mx]; vector<pair<int, pi>> updates[mx]; vpi res; vi R; vi cur; vpi getInts(const vi &a){ // cout << "Q: "; // for(auto u: a) cout << u << " "; // cout << "\n"; res.clear(); R = vi(sz(a), -1); cur.clear(); for(int i = sz(a)-1; i >= 0; i--){ while(sz(cur)){ if(a[cur.bk] <= a[i]){ cur.pop_back(); } else break; } if(sz(cur)) R[i] = cur.bk; cur.pb(i); } cur.clear(); for(int i = 0; i < sz(a); i++){ while(sz(cur)){ if(a[cur.bk] <= a[i]){ cur.pop_back(); } else break; } int L = -1; if(sz(cur)) L = cur.bk; cur.pb(i); if(R[i] != -1 && L != -1){ res.pb(mp(L+1, R[i]-1)); } } // vpi vals; // for(int i = 0; i < sz(a); i++){ // vals.pb(mp(a[i], i)); // } // sort(vals.rbegin(), vals.rend()); // set<int> poses; // for(int i = 0; i < sz(vals); i++){ // auto it1 = poses.lb(vals[i].s); // if(sz(poses) >= 2 && it1 != poses.end() && it1 != poses.begin()){ // int p1 = *(prev(it1)); // int p2 = *it1; // if(vals[i].f < min(a[p1], a[p2])){ // res.pb(mp(p1+1, p2-1)); // } // } // poses.ins(vals[i].s); // } // for(int i = 0; i < sz(vals); i++){ // pair<pi, pi> b = *(prev(rang.lb(mp(mp(vals[i].s, MOD), mp(0, 0))))); // //cout << i << "\n"; // assert(b.f.f <= vals[i].s && vals[i].s <= b.f.s); // rang.erase(b); // //if vals[i] is the max in range & if not on boundary // if(vals[i].f < min(b.s.f, b.s.s) && 1 <= b.f.f && b.f.s <= sz(a)-2){ // res.pb(b.f); // } // //only divide if range added // if(b.f.f <= vals[i].s-1){ // rang.ins(mp(mp(b.f.f, vals[i].s-1), mp(b.s.f, vals[i].f))); // } // if(vals[i].s+1 <= b.f.s){ // rang.ins(mp(mp(vals[i].s+1, b.f.s), mp(vals[i].f, b.s.s))); // } // } // cout << "R: "; // for(auto u: res) cout << "(" << u.f << " " << u.s << "), "; // cout << "\n"; return res; } int val[mx]; vi curin; void upd(int a, int v){ if(v == 1) curin.pb(a); for(; a < mx; a+=a&-a) val[a]+=v; } int sum(int a){ int res = 0; for(; a > 0; a-=a&-a) res+=val[a]; return res; } int query(int a, int b){ return sum(b)-sum(a-1); } void clearBIT(){ for(auto u: curin){ upd(u, -1); } curin.clear(); } ll count_rectangles(vector<vi> a){ // clock_t c = clock(); // cout << fixed << setprecision(5); // cout << double(clock()-c)/CLOCKS_PER_SEC << "\n"; n = sz(a); m = sz(a[0]); // double r1 = 0; // double r2 = 0; for(int i = 1; i+1 < n; i++){ vi nums; for(int j = 0; j < m; j++){ nums.pb(a[i][j]); } // clock_t d = clock(); vpi a = getInts(nums); // r1+=double(clock()-d)/CLOCKS_PER_SEC; // d = clock(); for(auto u: a){ ints2[i].ins(mx*u.f+u.s); } // r2+=double(clock()-d)/CLOCKS_PER_SEC; // d = clock(); } // cout << "r1: " << r1 << "\n"; // cout << "r2: " << r2 << "\n"; // cout << double(clock()-c)/CLOCKS_PER_SEC << "\n"; ht<int, null_type> vals; for(int i = 1; i+1 < n; i++){ vals = ints2[i]; for(auto x: vals){ int j = x/mx; int u = x % mx; for(int K = i; K+1 < n; K++){ if(ints2[K+1].find(mx*j+u) == ints2[K+1].end()){ for(int k = i; k <= K; k++){ queries[k].pb(mp(j, mp(K, u))); //cout << "Q: " << k << " " << j << " " << K << " " << u << "\n"; ints2[k].erase(mx*j+u); } break; } } } } // cout << double(clock()-c)/CLOCKS_PER_SEC << "\n"; for(int i = 0; i < mx; i++){ ints2[i].clear(); } for(int j = 1; j+1 < m; j++){ //cout << "j: " << j << "\n"; vi nums; for(int i = 0; i < n; i++){ nums.pb(a[i][j]); } vpi a = getInts(nums); // cout << "a: " << "\n"; // for(auto u: a){ // cout << u.f << " " << u.s << "\n"; // } for(auto u: a){ ints2[j].ins(mx*u.f+u.s); //ints[u.f][j].ins(u.s); } } for(int j = 1; j+1 < m; j++){ vals = ints2[j]; for(auto x: vals){ int i = x/mx; int u = x % mx; for(int K = j; K+1 < m; K++){ if(ints2[K+1].find(mx*i+u) == ints2[K+1].end()){ for(int k = j; k <= K; k++){ updates[i].pb(mp(k, mp(u, K))); //cout << "U: " << i << " " << k << " " << u << " " << K << "\n"; //cout << i << " " << j << " " << k << "\n"; ints2[k].erase(mx*i+u); } break; } } } } // cout << double(clock()-c)/CLOCKS_PER_SEC << "\n"; ll ans = 0; for(int i = 1; i+1 < n; i++){ sort(all(queries[i])); sort(all(updates[i])); int updind = 0; int lasty = -1; for(auto u: queries[i]){ if(u.f != lasty) clearBIT(); while(updind < sz(updates[i])){ if(updates[i][updind].f < u.f){ updind++; continue; } if(updates[i][updind].f > u.f){ break; } if(updates[i][updind].s.f <= u.s.f){ upd(updates[i][updind].s.s, 1); updind++; continue; } else break; } ans+=query(u.s.s, 2504); lasty = u.f; } // for(int j = 1; j+1 < m; j++){ // sort(all(queries[i][j])); // sort(all(updates[i][j])); // int updind = 0; // for(auto u: queries[i][j]){ // while(updind < sz(updates[i][j])){ // if(updates[i][j][updind].f <= u.f){ // upd(updates[i][j][updind].s, 1); // updind++; // } // else break; // } // //if(query(u.s, 2504) > 0) cout << i << " " << j << "\n"; // ans+=query(u.s, 2504); //number of things >= // } // clearBIT(); // } } // cout << double(clock()-c)/CLOCKS_PER_SEC << "\n"; 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...