제출 #735503

#제출 시각아이디문제언어결과실행 시간메모리
735503vjudge1수열 (APIO14_sequence)C++17
0 / 100
56 ms14644 KiB
#include <bits/stdc++.h>
using namespace std;

class cht_t {
       public:
        class line_t {
               public:
                int64_t a, b;
                line_t(int64_t a, int64_t b) : a(a), b(b) {}
                int64_t operator()(const int64_t& x) const { return a * x + b; }
                int64_t intersect(const line_t& other) const {
                        int64_t x = (b - other.b) / (other.a - a);
                        while ((*this)(x) <= other(x)) x--;
                        while ((*this)(x) > other(x)) x++;
                        return x;
                }
        };
        deque<pair<line_t, int>> dq;

        void insert(int64_t a, int64_t b, int id) {
                line_t newline(a, b);
                while (dq.size() > 1 && dq.back().first.intersect(dq[dq.size() - 2].first) >= newline.intersect(dq.back().first)) dq.pop_back();
                dq.emplace_back(newline, id);
        }

        pair<int64_t, int> getmin(const int64_t& x) {
                while (dq.size() > 1 && dq[0].first(x) >= dq[1].first(x)) dq.pop_front();
                return {dq[0].first(x), dq[0].second};
        }
};

int main() {
        int n, k;
        cin >> n >> k;
        k++;
        vector<int> a;
        for (int i = 0; i < n; i++) {
                int x;
                cin >> x;
                if (x) a.emplace_back(x);
        }
        n = a.size();
        k = min(k, n);
        int64_t res = 1ll * accumulate(a.begin(), a.end(), 0ll) * accumulate(a.begin(), a.end(), 0ll);
        for (int i = 0; i < n; i++) res -= 1ll * a[i] * a[i];
        // f[i][j] = min(f[k][j - 1] + (ps[i] - ps[k]) * (ps[i] - ps[k]))
        // f[i][j] = min(f[k][j - 1] + ps[k] * ps[k] + pss[k] - 2 * ps[k] * ps[i]) + ps[i] * ps[i] - pss[i];
        //                -----------------v-----------------   ----v----  ---v---
        //                                 b                        a         x
        vector<vector<int64_t>> f(n, vector<int64_t>(k));
        vector<vector<int>> trace(n, vector<int>(k));
        vector<cht_t> cht(k);
        int64_t ps = 0, pss = 0;
        for (int i = 0; i < n; i++) {
                ps += a[i], pss += 1ll * a[i] * a[i];
                for (int j = k - 1; j >= 0; j--) {
                        if (j > i) continue;
                        if (j) {
                                auto p = cht[j - 1].getmin(ps);
                                f[i][j] = p.first + ps * ps - pss;
                                trace[i][j] = p.second;
                        } else {
                                f[i][j] = ps * ps - pss;
                                trace[i][j] = -1;
                        }
                        cht[j].insert(-2 * ps, f[i][j] + ps * ps + pss, i);
                }
        }
        vector<int> ans;
        int ii = n - 1, jj = k - 1;
        while (ii != -1) ans.emplace_back(trace[ii][jj] + 1), ii = trace[ii][jj], jj--;
        ans.pop_back();
        reverse(ans.begin(), ans.end());
        cout << (res - f[n - 1][k - 1]) / 2 << '\n';
        for (int x : ans) cout << x << ' ';
}
#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...