Submission #1249091

#TimeUsernameProblemLanguageResultExecution timeMemory
1249091Zbyszek99축구 경기장 (IOI23_soccer)C++20
70 / 100
4643 ms1185636 KiB
#include "soccer.h" #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ld long double #define ull unsigned long long #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define vi vector<int> #define vl vector<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 __gnu_pbds; using namespace std; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; //mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());} //ll los(ll a, ll b) {return a + (mt() % (b-a+1));} const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9+7; struct block { int x1,x2,y1,y2,x3; bool operator<(const block& other) { return (y2-y1) < (other.y2-other.y1); } }; int arr[2003][2003]; int pref[2003][2003]; vi ones[2003]; int nxt_one[2003][2003]; int one_cnt[2003][2003]; vector<block> blocks[2003]; int ans = 0; unordered_map<int,int> ans_map[2003][2003]; unordered_map<ll,int> total_map; ll hash_rect(ll x1, ll x2, ll y1, ll y2) { return x1 + x2*2005LL + y1*2005LL*2005LL + y2*2005LL*2005LL*2005LL; } int biggest_stadium(int n, vector<vi> F) { rep2(i,0,n+2) { rep2(j,0,n+2) { arr[i][j] = 1; } } rep2(i,1,n) { rep2(j,1,n) { arr[i][j] = F[i-1][j-1]; } } rep2(i,1,n) { rep2(j,1,n) { pref[i][j] = pref[i][j-1] + pref[i-1][j] - pref[i-1][j-1] + arr[i][j]; } } rep2(i,0,n+1) { rep2(j,1,n) { if(arr[i][j] == 1) { int p = i-1; while(p >= 0 && arr[p][j] == 0) { int lb = j; int rb = j; int l = 1; int r = j; while(l <= r) { int mid = (l+r)/2; if(pref[i-1][j]-pref[i-1][mid-1]-pref[p-1][j]+pref[p-1][mid-1] == 0) { lb = mid; r = mid-1; } else { l = mid+1; } } l = j; r = n; while(l <= r) { int mid = (l+r)/2; if(pref[i-1][mid]-pref[i-1][j-1]-pref[p-1][mid]+pref[p-1][j-1] == 0) { rb = mid; l = mid+1; } else { r = mid-1; } } blocks[(i-1)-p].pb({lb,rb,p,i-1,j}); p--; } p = i+1; while(p <= n && arr[p][j] == 0) { int lb = j; int rb = j; int l = 1; int r = j; while(l <= r) { int mid = (l+r)/2; if(pref[p][j]-pref[p][mid-1]-pref[i][j]+pref[i][mid-1] == 0) { lb = mid; r = mid-1; } else { l = mid+1; } } l = j; r = n; while(l <= r) { int mid = (l+r)/2; if(pref[p][mid]-pref[p][j-1]-pref[i][mid]+pref[i][j-1] == 0) { rb = mid; l = mid+1; } else { r = mid-1; } } blocks[p-(i+1)].pb({lb,rb,i+1,p,j}); p++; } } } } rep(j,n+2) { int cnt = 0; rep(i,n+2) { if(arr[i][j] == 1) { ones[j].pb(i); one_cnt[i][j] = cnt++; } } } rep(j,n+2) { nxt_one[j][siz(ones[j])] = siz(ones[j]); ones[j].pb(n+2); } for(int i = n+1; i >= 0; i--) { rep(j,n+2) { if(arr[i][j] == 0) { continue; } else { if(i != 0 && arr[i-1][j] == 0) nxt_one[j][one_cnt[i][j]] = one_cnt[i][j]; else { nxt_one[j][one_cnt[i][j]] = nxt_one[j][one_cnt[i][j]+1]; } } } } rep(d,n) { forall(it,blocks[d]) { ll h = hash_rect(it.x1,it.y1,it.x2,it.y2); if(total_map.find(h) != total_map.end()) { int best = total_map[h]; ans_map[it.x3][it.y1][it.y2] = max(ans_map[it.x3][it.y1][it.y2],best); continue; } int best = (it.x2-it.x1+1)*(it.y2-it.y1+1); int l = 0; int r = siz(ones[it.x1-1])-1; int a = 0; while(l <= r) { int mid = (l+r)/2; if(ones[it.x1-1][mid] >= it.y1) { a = mid; r = mid-1; } else { l = mid+1; } } while(ones[it.x1-1][a-1] < it.y2) { l = max(it.y1,ones[it.x1-1][a-1]+1); r = min(it.y2,ones[it.x1-1][a]-1); if(l <= r) { best = max(best,ans_map[it.x1-1][l][r]+(it.x2-it.x1+1)*(it.y2-it.y1+1)-(r-l+1)*(it.x2-it.x1+1)); } a = nxt_one[it.x1-1][a+1]; // cerr << a << " " << it.x1-1 << " a\n"; } l = 0; r = siz(ones[it.x2+1])-1; a = 0; while(l <= r) { int mid = (l+r)/2; if(ones[it.x2+1][mid] >= it.y1) { a = mid; r = mid-1; } else { l = mid+1; } } while(ones[it.x2+1][a-1] < it.y2) { l = max(it.y1,ones[it.x2+1][a-1]+1); r = min(it.y2,ones[it.x2+1][a]-1); if(l <= r) { best = max(best,ans_map[it.x2+1][l][r]+(it.x2-it.x1+1)*(it.y2-it.y1+1)-(r-l+1)*(it.x2-it.x1+1)); } a = nxt_one[it.x2+1][a+1]; // cerr << a << " " << it.x2+1 << " " << ones[it.x2+1][a-1]<< " a2\n"; } ans = max(ans,best); ans_map[it.x3][it.y1][it.y2] = max(ans_map[it.x3][it.y1][it.y2],best); total_map[h] = best; } } 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...