Submission #597679

#TimeUsernameProblemLanguageResultExecution timeMemory
597679FatihSolakRectangles (IOI19_rect)C++17
72 / 100
5083 ms530132 KiB
#include "rect.h" #include <bits/stdc++.h> #define N 2505 using namespace std; struct BIT{ vector<short> bit; short n; BIT(short size){ n = size + 5; bit.assign(n+5,0); } void upd(short pos,short val){ for(++pos;pos<n;pos += pos & -pos){ bit[pos] += val; } } short get(short pos){ short ret = 0; for(++pos;pos > 0;pos -= pos & -pos){ ret += bit[pos]; } return ret; } short get(short l,short r){ return get(r) - get(l-1); } }; struct SegTree{ vector<BIT> t; short n; SegTree(short size){ n = size + 5; t.assign(4*n,BIT(n)); } void upd(short v,short tl,short tr,short l,short r,short val){ //cout << val << endl; t[v].upd(r,val); if(tl == tr)return; short tm = (tl + tr)/2; if(l <= tm){ upd(v*2,tl,tm,l,r,val); } else upd(v*2+1,tm+1,tr,l,r,val); } short get(short v,short tl,short tr,short l,short r){ if(tr <= l){ return t[v].get(r,n-1); } if(tl > l){ return 0; } short tm = (tl + tr)/2; return get(v*2,tl,tm,l,r) + get(v*2+1,tm+1,tr,l,r); } void upd(short l,short r,short val){ upd(1,0,n-1,l,r,val); } short get(short l,short r){ return get(1,0,n-1,l,r); } }; short mp[N][N]; vector<short> pos[N]; vector<short> prepos[N]; vector<pair<short,short>> ranges[N][N]; vector<pair<short,short>> queries[N][N]; long long count_rectangles(vector<vector<int>> a){ short n = a.size(); short m = a[0].size(); //cout << n << " " << m << endl; if(n < 3 || m < 3){ return 0; } for(short i = m-1;i>=0;i--){ vector<short> st; for(short j = 0;j<n;j++){ while(st.size() && a[j][i] > a[st.back()][i]) st.pop_back(); if(st.size() && st.back() != j-1 && a[st.back()][i] != a[j][i]){ pos[st.back()].push_back(j); } st.push_back(j); } st.clear(); for(short j = n-1;j>=0;j--){ while(st.size() && a[j][i] > a[st.back()][i]) st.pop_back(); if(st.size() && st.back() != j+1){ pos[j].push_back(st.back()); } st.push_back(j); } for(short j = 0;j<n;j++){ for(auto u:prepos[j]){ mp[j][u] = -mp[j][u]; } } for(short j = 0;j<n;j++){ for(auto u:pos[j]){ mp[j][u] = 1 - mp[j][u]; if(i) queries[i-1][mp[j][u]+1].push_back({j+1,u-1}); //cout << i << " " << mp[j][u] << " " << j << " " << u << endl; } } for(short j = 0;j<n;j++){ for(auto u:prepos[j]){ if(mp[j][u] < 0) mp[j][u] = 0; } swap(prepos[j],pos[j]); pos[j].clear(); } } for(short i = 0;i<N;i++){ pos[i].clear(); prepos[i].clear(); for(short j = 0;j<N;j++){ mp[i][j] = 0; } } for(short i = n-1;i>=0;i--){ vector<short> st; for(short j = 0;j<m;j++){ while(st.size() && a[i][j] > a[i][st.back()]) st.pop_back(); if(st.size() && st.back() != j-1 && a[i][j] != a[i][st.back()]){ pos[st.back()].push_back(j); } st.push_back(j); } st.clear(); for(short j = m-1;j>=0;j--){ while(st.size() && a[i][j] > a[i][st.back()]) st.pop_back(); if(st.size() && st.back() != j+1){ pos[j].push_back(st.back()); } st.push_back(j); } for(short j = 0;j<m;j++){ for(auto u:prepos[j]){ mp[j][u] = -mp[j][u]; } } for(short j = 0;j<m;j++){ for(auto u:pos[j]){ mp[j][u] = 1 - mp[j][u]; } } for(short j = 0;j<m;j++){ for(auto u:prepos[j]){ if(mp[j][u] < 0){ //cout << j << " " << u << " " << i + 1 << " " << i - mp[j][u] << endl; ranges[j][u-j].push_back({i+1,i - mp[j][u]}); mp[j][u] = 0; } } swap(prepos[j],pos[j]); pos[j].clear(); } } for(short j = 0;j<m;j++){ for(auto u:prepos[j]){ if(mp[j][u] > 0){ //cout << j << " " << u << " " << -1 + 1 << " " << -1 + mp[j][u] << endl; ranges[j][u-j].push_back({-1+1,-1 + mp[j][u]}); mp[j][u] = 0; } } } SegTree tree(n); long long ans = 0; for(short i = 0;i<m;i++){ for(short j = 0;j<=m+1;j++){ for(auto u:ranges[i][j]){ //cout << "add" << u.first << " " << u.second << endl; tree.upd(u.first,u.second,1); } for(auto u:queries[i][j]){ //cout << "..." << i << " " << i+j << " " << u.first << " " << u.second << endl; ans += tree.get(u.first,u.second); //cout << ans << endl; } } for(short j = 0;j<=m+1;j++){ for(auto u:ranges[i][j]){ //cout << "del" << u.first << " " << u.second << endl; tree.upd(u.first,u.second,-1); } } } 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...