제출 #368024

#제출 시각아이디문제언어결과실행 시간메모리
368024KoD선물상자 (IOI15_boxes)C++17
50 / 100
103 ms39880 KiB
#ifndef LOCAL
#include "boxes.h"
#endif

#include <vector>
#include <algorithm>
#include <iostream>
#include <numeric>

template <class T>
using Vec = std::vector<T>;

constexpr long long INF = std::numeric_limits<long long>::max();

template <class Select>
Vec<int> smawk(const int R, const int C, const Select &select) {
    const auto dfs = [&](const auto dfs, const Vec<int> &row, const Vec<int> &column) -> Vec<int> {
        if (row.empty()) {
            return { };
        }
        Vec<int> cs;
        cs.reserve(row.size());
        for (const auto c: column) {
            while (!cs.empty() && select(row[cs.size() - 1], cs.back(), c)) {
                cs.pop_back();
            }
            if (cs.size() < row.size()) {
                cs.push_back(c);
            }
        }
        Vec<int> rs;
        rs.reserve(row.size() / 2);
        for (int i = 1; i < (int) row.size(); i += 2) {
            rs.push_back(row[i]);
        }
        const auto half = dfs(dfs, rs, cs);
        Vec<int> ret(row.size());
        int idx = 0;
        for (int i = 0; i < (int) row.size(); ++i) {
            if (i & 1) {
                ret[i] = half[i / 2];
            }
            else {
                ret[i] = cs[idx];
                const auto next = (i + 1 == (int) row.size() ? cs.back() : half[i / 2]);
                while (cs[idx] < next) {
                    idx += 1;
                    if (select(row[i], ret[i], cs[idx])) {
                        ret[i] = cs[idx];
                    }
                }
            }
        }
        return ret;
    };
    Vec<int> row(R);
    std::iota(row.begin(), row.end(), 0);
    Vec<int> column(C);
    std::iota(column.begin(), column.end(), 0);
    return dfs(dfs, row, column);
}

Vec<long long> convolve(const Vec<long long> &A, const Vec<long long> &B) {
    const int N = (int) A.size();
    const int M = (int) B.size();
    const auto get = [&](const int i, const int j) {
        return A[j] + B[i - j];
    };
    const auto select = [&](const int i, const int j, const int k) {
        if (j > i || i >= M + j) return true;
        if (k > i) return false;
        return get(i, j) >= get(i, k);
    };
    Vec<long long> ret(N + M - 1);
    const auto best = smawk(N + M - 1, N, select);
    for (int i = 0; i < N + M - 1; ++i) {
        ret[i] = get(i, best[i]);
    }
    return ret;
}

long long delivery(int N, int K, int Len, int P[]) {
    Vec<int> left, right;
    left.reserve(N);
    right.reserve(N);
    for (int i = 0; i < N; ++i) {
        const auto l = P[i];
        const auto r = Len - P[i];
        if (l <= r) {
            left.push_back(l);
        }
        else {
            right.push_back(r);
        }
    } 
    std::reverse(right.begin(), right.end());
    const int L = (int) left.size();
    const int R = (int) right.size();
    Vec<long long> dp_l(L + 1), dp_r(R + 1);
    for (int i = 1; i <= L; ++i) {
        dp_l[i] = dp_l[(i >= K ? i - K : 0)] + 2 * left[i - 1];
    }
    for (int i = 1; i <= R; ++i) {
        dp_r[i] = dp_r[(i >= K ? i - K : 0)] + 2 * right[i - 1];
    }
    const auto dp = convolve(dp_l, dp_r);
    long long ret = INF;
    for (int i = 0; i <= N; ++i) {
        const auto first = (long long) Len * ((N - i + K - 1) / K);
        const auto second = dp[i];
        ret = std::min(ret, first + second);
    }
    return ret;
}

#ifdef LOCAL 
int main() {
    int N, K, L;
    std::cin >> N >> K >> L;
    int P[100] = {};
    for (int i = 0; i < N; ++i) {
        std::cin >> P[i];
    }
    std::cout << delivery(N, K, L, P) << '\n';
    return 0;
}
#endif

컴파일 시 표준 에러 (stderr) 메시지

boxes.cpp: In lambda function:
boxes.cpp:17:90: warning: declaration of 'dfs' shadows a previous local [-Wshadow]
   17 |     const auto dfs = [&](const auto dfs, const Vec<int> &row, const Vec<int> &column) -> Vec<int> {
      |                                                                                          ^~~~~~~~
boxes.cpp:17:16: note: shadowed declaration is here
   17 |     const auto dfs = [&](const auto dfs, const Vec<int> &row, const Vec<int> &column) -> Vec<int> {
      |                ^~~
boxes.cpp: In instantiation of 'Vec<int> smawk(int, int, const Select&) [with Select = convolve(Vec<long long int>&, Vec<long long int>&)::<lambda(int, int, int)>; Vec<int> = std::vector<int, std::allocator<int> >]':
boxes.cpp:75:49:   required from here
boxes.cpp:17:22: warning: declaration of 'dfs' shadows a previous local [-Wshadow]
   17 |     const auto dfs = [&](const auto dfs, const Vec<int> &row, const Vec<int> &column) -> Vec<int> {
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   18 |         if (row.empty()) {
      |         ~~~~~~~~~~~~~~~~~~
   19 |             return { };
      |             ~~~~~~~~~~~
   20 |         }
      |         ~             
   21 |         Vec<int> cs;
      |         ~~~~~~~~~~~~  
   22 |         cs.reserve(row.size());
      |         ~~~~~~~~~~~~~~~~~~~~~~~
   23 |         for (const auto c: column) {
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   24 |             while (!cs.empty() && select(row[cs.size() - 1], cs.back(), c)) {
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   25 |                 cs.pop_back();
      |                 ~~~~~~~~~~~~~~
   26 |             }
      |             ~         
   27 |             if (cs.size() < row.size()) {
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   28 |                 cs.push_back(c);
      |                 ~~~~~~~~~~~~~~~~
   29 |             }
      |             ~         
   30 |         }
      |         ~             
   31 |         Vec<int> rs;
      |         ~~~~~~~~~~~~  
   32 |         rs.reserve(row.size() / 2);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   33 |         for (int i = 1; i < (int) row.size(); i += 2) {
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   34 |             rs.push_back(row[i]);
      |             ~~~~~~~~~~~~~~~~~~~~~
   35 |         }
      |         ~             
   36 |         const auto half = dfs(dfs, rs, cs);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   37 |         Vec<int> ret(row.size());
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~
   38 |         int idx = 0;
      |         ~~~~~~~~~~~~  
   39 |         for (int i = 0; i < (int) row.size(); ++i) {
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   40 |             if (i & 1) {
      |             ~~~~~~~~~~~~
   41 |                 ret[i] = half[i / 2];
      |                 ~~~~~~~~~~~~~~~~~~~~~
   42 |             }
      |             ~         
   43 |             else {
      |             ~~~~~~    
   44 |                 ret[i] = cs[idx];
      |                 ~~~~~~~~~~~~~~~~~
   45 |                 const auto next = (i + 1 == (int) row.size() ? cs.back() : half[i / 2]);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   46 |                 while (cs[idx] < next) {
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~
   47 |                     idx += 1;
      |                     ~~~~~~~~~
   48 |                     if (select(row[i], ret[i], cs[idx])) {
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   49 |                         ret[i] = cs[idx];
      |                         ~~~~~~~~~~~~~~~~~
   50 |                     }
      |                     ~ 
   51 |                 }
      |                 ~     
   52 |             }
      |             ~         
   53 |         }
      |         ~             
   54 |         return ret;
      |         ~~~~~~~~~~~   
   55 |     };
      |     ~                 
boxes.cpp:17:16: note: shadowed declaration is here
   17 |     const auto dfs = [&](const auto dfs, const Vec<int> &row, const Vec<int> &column) -> Vec<int> {
      |                ^~~
#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...