제출 #843062

#제출 시각아이디문제언어결과실행 시간메모리
843062nonono축구 경기장 (IOI23_soccer)C++17
100 / 100
1660 ms314288 KiB
#include "soccer.h"
#include <bits/stdc++.h>
using namespace std;

const int mxN = 2000;

map<int, int> dp[mxN][mxN];

int full(int N, vector<vector<int>> F) {
    vector<vector<int>> sum(N, vector<int> (N, 0));
    for(int i = 0; i < N; i ++) {
        for(int j = 0; j < N; j ++) {
            sum[i][j] = F[i][j];
            
            if(i) sum[i][j] += sum[i - 1][j];
            if(j) sum[i][j] += sum[i][j - 1];
            if(i && j) sum[i][j] -= sum[i - 1][j - 1]; 
            
        }
    }
    
    auto Area = [&] (int x, int y, int u, int v) {
        return sum[u][v] - (x ? sum[x - 1][v] : 0) - (y ? sum[u][y - 1] : 0) + (x && y ? sum[x - 1][y - 1] : 0);
    };
    
    auto Range = [&] (int x, int L, int R) {
        int low = x, high = x - 1;
        for(int i = 10; i >= 0; i --) {
            if(low - (1 << i) >= 0 && Area(low - (1 << i), L, x, R) == 0) low -= (1 << i);
            if(high + (1 << i) < N && Area(x, L, high + (1 << i), R) == 0) high += (1 << i);
        }
        
        return make_pair(low, high);
    };   
    
    function<int(int, int, int)> DP = [&] (int x, int L, int R) {
        if(dp[L][R].count(x)) return dp[L][R][x];
        auto [low, high] = Range(x, L, R);
        if(x != low) return DP(low, L, R);
        
        int ans = 0;
        for(int i = L; i <= R; i ++) {
            auto check = [&] (int r) {
                return low - 1 >= 0 && Area(low - 1, i, low - 1, r) == 0;
            };
            
            if(check(i) == 0) continue ;
            
            int j = i;
            for(int k = 10; k >= 0; k --) if(j + (1 << k) <= R && check(j + (1 << k))) j += (1 << k);
            auto [_low, _high] = Range(low - 1, i, j);
            ans = max(ans, DP(_low, i, j) + (low - _low + _high - high) * (j - i + 1));
            i = j;
        }
        
        for(int i = L; i <= R; i ++) {
            auto check = [&] (int r) {
                return high + 1 < N && Area(high + 1, i, high + 1, r) == 0;
            };
            
            if(check(i) == 0) continue ;
            
            int j = i;
            for(int k = 10; k >= 0; k --) if(j + (1 << k) <= R && check(j + (1 << k))) j += (1 << k);
            auto [_low, _high] = Range(high + 1, i, j);
            ans = max(ans, DP(_low, i, j) + (low - _low + _high - high) * (j - i + 1));
            i = j;
        }
        
        return dp[L][R][x] = ans;
    };
    
    int result = 0;
    for(int i = 0; i < N; i ++) {
        pair<int, int> x = Range(i, 0, N - 1);
        result = max(result, DP(i, 0, N - 1) + (x.second - x.first + 1) * N);
    }
    
    return result;
}
 
int biggest_stadium(int N, vector<vector<int>> F) {
    return full(N, F);
}
#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...