Submission #1241827

#TimeUsernameProblemLanguageResultExecution timeMemory
1241827Zbyszek99Rectangles (IOI19_rect)C++20
72 / 100
2567 ms1114112 KiB
#include "rect.h" #include <bits/stdc++.h> #define ll long long #define ld long double #define vi vector<int> #define vl vector<long long> #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define pb push_back #define rep(i, b) for(int i = 0; i < (b); ++i) #define rep2(i,a,b) for(int i = a; i <= (b); ++i) #define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c) #define count_bits(x) __builtin_popcountll((x)) #define all(x) (x).begin(),(x).end() #define siz(x) (int)(x).size() #define forall(it,x) for(auto& it:(x)) using namespace std; const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9+7; const int tree_siz = 1024*8-1; int sum[tree_siz+1]; int get_sum(int akt, int p1, int p2, int s1, int s2) { if(p2 < s1 || p1 > s2) return 0; if(p1 >= s1 && p2 <= s2) return sum[akt]; return get_sum(akt*2,p1,(p1+p2)/2,s1,s2)+get_sum(akt*2+1,(p1+p2)/2+1,p2,s1,s2); } void upd(int v) { sum[v] = sum[v*2]+sum[v*2+1]; if(v != 1) upd(v/2); } void change(int ind, int x) { sum[tree_siz/2+ind+1] += x; upd((tree_siz/2+1+ind)/2); } int cp(pii x) { return x.ff * 2600 + x.ss; } pii de(int x) { return {x/2600,x%2600}; } map<int,short> X[2501]; map<int,short> Y[2501]; vi X_segs[2501][2501]; vi Y_segs[2501][2501]; vi count_regions(vi& x) { vi ans; stack<int> st; rep(i,siz(x)) { while(!st.empty() && x[st.top()] < x[i]) st.pop(); if(i != 0 && siz(st) != 0) { int end_ = st.top()+1; if(end_ <= i-1) { ans.pb(cp({end_,i-1})); } } st.push(i); } while(!st.empty()) st.pop(); for(int i = siz(x)-1; i >= 0; i--) { while(!st.empty() && x[st.top()] < x[i]) st.pop(); if(i != siz(x)-1 && siz(st) != 0) { int end_ = st.top()-1; if(end_ >= i+1) { ans.pb(cp({i+1,end_})); } } st.push(i); } sort(all(ans)); vi ans2; int pop = -1; forall(it2,ans) { if(it2 == pop) continue; ans2.pb(it2); pop = it2; } return ans2; } ll count_rectangles(vector<vi> arr) { int n = siz(arr); int m = siz(arr[0]); vi segs; rep2(i,1,n-2) { segs = count_regions(arr[i]); forall(it,segs) { Y[i][it] = i; } } for(int i = n-2; i >= 0; i--) { pii it; forall(it2,Y[i]) { it = de(it2.ff); if(Y[i+1].find(it2.ff) != Y[i+1].end()) Y[i][it2.ff] = Y[i+1][it2.ff]; Y_segs[i][it.ff].pb(cp({Y[i][it2.ff],it.ss})); } } vi arr2(n); rep2(j,1,m-2) { rep(i,n) arr2[i] = arr[i][j]; segs = count_regions(arr2); forall(it,segs) { X[j][it] = j; } } for(int j = m-2; j >= 0; j--) { pii it; forall(it2,X[j]) { it = de(it2.ff); if(X[j+1].find(it2.ff) != X[j+1].end()) X[j][it2.ff] = X[j+1][it2.ff]; X_segs[it.ff][j].pb(cp({it.ss,X[j][it2.ff]})); } } ll ans = 0; rep2(i,1,n-2) { rep2(j,1,m-2) { sort(all(X_segs[i][j])); sort(all(Y_segs[i][j])); reverse(all(Y_segs[i][j])); int cur_Y = siz(Y_segs[i][j])-1; forall(it,Y_segs[i][j]) { change(it % 2600,1); } forall(it,X_segs[i][j]) { while(cur_Y >= 0 && Y_segs[i][j][cur_Y]/2600 < it/2600) { change(Y_segs[i][j][cur_Y]%2600,-1); cur_Y--; } ans += get_sum(1,0,tree_siz/2,0,it%2600); } rep(k,cur_Y+1) { change(Y_segs[i][j][k]%2600,-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...