제출 #562754

#제출 시각아이디문제언어결과실행 시간메모리
562754Cyanmond수열 (APIO14_sequence)C++17
100 / 100
842 ms86460 KiB
#include <bits/stdc++.h>

using namespace std;
using i64 = int64_t;

constexpr i64 inf = 1ll << 40;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REP3(i, l, r) for (int i = (l); i < (r); ++i)

template <typename T> bool chmax(T &a, const T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

class CHT {
    deque<pair<i64, i64>> deq;

    int pm(i64 v) { return v == 0 ? 0 : (v > 0 ? 1 : -1); }

    bool check(pair<i64, i64> a, pair<i64, i64> b, pair<i64, i64> c) {
        if (a.second == b.second or b.second == c.second)
            return pm(b.first - a.first) * pm(c.second - b.second) <=
                   pm(c.first - b.first) * pm(b.second - a.second);
        else
            return double(b.first - a.first) * pm(c.second - b.second) /
                       double(abs(b.second - a.second)) <=
                   double(c.first - b.first) * pm(b.second - a.second) /
                       double(abs(c.second - b.second));
    }

  public:
    void add(pair<i64, i64> line) {
        if (deq.empty()) {
            deq.push_back(line);
            return;
        }
        assert(line.first >= deq.back().first);
        if (deq.back().first == line.first) {
            if (deq.back().second > line.second)
                deq.pop_back();
            else
                return;
        }
        while (deq.size() >= 2 and check(deq[deq.size() - 2], deq.back(), line)) deq.pop_back();
        deq.push_back(line);
    }

    pair<i64, i64> query(i64 x) {
        while (deq.size() >= 2 and
               (deq[0].first * x + deq[0].second >= deq[1].first * x + deq[1].second))
            deq.pop_front();
        return {deq[0].first, deq[0].first * x + deq[0].second};
    }
};

int main() {
    int N, K;
    cin >> N >> K;
    ++K;
    vector<i64> A(N);
    for (auto &e : A) cin >> e;
    vector<i64> R(N + 1);
    REP(i, N) R[i + 1] = R[i] + A[i];
    auto calc_sum = [&R](int l, int r) { return R[r] - R[l]; };

    vector<i64> dp(N + 1, -inf);
    dp[0] = 0;
    vector<vector<int>> db(N + 1, vector<int>(K + 1));
    REP(k, K) {
        CHT cht;
        cht.add({calc_sum(0, k), -dp[k]});
        auto ndp = dp;
        REP3(i, k + 1, N + 1) {
            const auto [x, v] = cht.query(calc_sum(i, N));
            ndp[i] = -v + calc_sum(0, i) * calc_sum(i, N);
            db[i][k + 1] = x;
            if (i != N) cht.add({calc_sum(0, i), -dp[i]});
        }
        dp = move(ndp);
    }

    cout << dp[N] << endl;
    int now = N;
    vector<int> data;
    REP(i, K - 1) {
        int nxt = now;
        --nxt;
        while (calc_sum(0, nxt) != db[now][K - i]) --nxt;
        data.push_back(nxt);
        now = nxt;
    }
    reverse(data.begin(), data.end());
    REP(i, K - 1) cout << data[i] << (i == K - 1 ? '\n' : ' ');
}
#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...