#include "soccer.h"
#include <iostream>
#include <vector>
#include <array>
#define ll long long
using namespace std;
struct MonotoneQueue{
vector <array<ll, 2>> st;
void push_back(ll u, ll id) {
while (!st.empty() && st.back()[0] <= u) st.pop_back();
st.push_back({u, id});
}
void pop_back(ll u) {
if (!st.empty() && st.back()[1] == u) st.pop_back();
}
ll query() {
return st.empty() ? 0LL : st.back()[0];
}
void clear() {
st.clear();
}
}Q;
struct SegTree{
ll st[8000];
void init() {
for (int i=0; i<8000; ++i) st[i] = -1;
}
void update(ll id, ll l, ll r, ll q, ll w) {
if (l == r) {
st[id] = w;
return;
}
ll mid = (l+r)/2;
if (q <= mid) update(id*2, l, mid, q, w);
else update(id*2+1, mid+1, r, q, w);
st[id] = max(st[id*2], st[id*2+1]);
}
ll query(ll id, ll l, ll r, ll ql, ll qr) {
if (qr < l || r < ql) return -1;
else if (ql <= l && r <= qr) return st[id];
ll mid = (l+r)/2;
return max(query(id*2, l, mid, ql, qr), query(id*2+1, mid+1, r, ql, qr));
}
}ST;
ll dpR[2000][2000], dpL[2000][2000], nxR[2000][2000], nxL[2000][2000], ans[2000][2000];
void solve(int N, vector<vector<int>> F) {
ST.init();
for (int i=0; i<N; ++i) {
ll p = -1;
for (int j=0; j<N; ++j) {
if (F[i][j]) p = j;
nxL[i][j] = p;
}
p = N;
for (int j=N-1; j>=0; --j) {
if (F[i][j]) p = j;
nxR[i][j] = p;
}
}
ll u;
for (ll i=0; i<N; ++i) {
for (ll j=0; j<N; ++j) {
dpR[i][j] = dpL[i][j] = (ll)-1e18;
if (F[i][j]) continue;
if (!i) dpR[i][j] = nxR[i][j]-j;
else {
if (!j || F[i][j-1]) {
u = i-1;
Q.clear();
for (int k=j; k<nxR[i][j]; ++k) {
if (F[i-1][k]) continue;
if (k == j || F[i-1][k-1]) {
if (nxR[i-1][k] <= nxR[i][j]) Q.push_back(dpR[i-1][k], k);
else {
Q.push_back(dpL[i-1][nxR[i][j]-1], k);
break;
}
}
}
}
dpR[i][j] = max(Q.query(), (u != -1 && !F[u][j] && nxR[u][j] <= nxR[i][j] ? dpR[u][j] : (ll)-1e18)) + (nxR[i][j]-j) * (i-u);
Q.pop_back(j);
if (j+1 != nxR[i][j] && Q.st.empty()) {
u = ST.query(1, 0, N-1, j+1, nxR[i][j]-1);
if (u != -1) {
for (int k=j+1; k<nxR[i][j]; ++k) {
if (F[u][k]) continue;
if (k == j+1 || F[u][k-1]) {
if (nxR[u][k] <= nxR[i][j]) Q.push_back(dpR[u][k], k);
else {
Q.push_back(dpL[u][nxR[i][j]-1], k);
break;
}
}
}
}
}
}
}
for (int j=N-1; j>=0; --j) {
if (F[i][j]) {
ST.update(1, 0, N-1, j, i);
continue;
}
if (!i) dpL[i][j] = j-nxL[i][j];
else {
if (j == N-1 || F[i][j+1]) {
u = i-1;
Q.clear();
for (int k=j; k>nxL[i][j]; --k) {
if (F[i-1][k]) continue;
if (k == j || F[i-1][k+1]) {
if (nxL[i-1][k] >= nxL[i][j]) Q.push_back(dpL[i-1][k], k);
else {
Q.push_back(dpR[i-1][nxL[i][j]+1], k);
break;
}
}
}
}
dpL[i][j] = max(Q.query(), (u != -1 && !F[u][j] && nxL[u][j] >= nxL[i][j] ? dpL[u][j] : (ll)-1e18)) + (j-nxL[i][j]) * (i-u);
Q.pop_back(j);
if (j-1 != nxL[i][j] && Q.st.empty()) {
u = ST.query(1, 0, N-1, nxL[i][j]+1, j-1);
if (u != -1) {
for (int k=j-1; k>nxL[i][j]; --k) {
if (F[u][k]) continue;
if (k == j-1 || F[u][k+1]) {
if (nxL[u][k] >= nxL[i][j]) Q.push_back(dpL[u][k], k);
else {
Q.push_back(dpR[u][nxL[i][j]+1], k);
break;
}
}
}
}
}
}
}
}
}
int biggest_stadium(int N, std::vector<std::vector<int>> F)
{
solve(N, F);
for (int i=0; i<N; ++i) {
for (int j=0; j<N; ++j) {
ans[i][j] = dpR[i][j]-(nxR[i][j]-j);
}
}
for (int i=0; i<N/2; ++i) {
swap(F[i], F[N-1-i]);
}
solve(N, F);
int f = 0;
for (int i=0; i<N; ++i) {
for (int j=0; j<N; ++j) {
ans[i][j] += dpR[N-1-i][j];
ans[i][j] = max(0LL, ans[i][j]);
f = max(f, (int)ans[i][j]);
}
}
return f;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |