Submission #107921

#TimeUsernameProblemLanguageResultExecution timeMemory
107921SamAnd수열 (APIO14_sequence)C++17
71 / 100
2047 ms84648 KiB
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
const long long INF = 1000000009000000009;

int n, m;
int a[N];
long long p[N];

long long dp[N], ndp[N];
int pp[N][202];

vector<int> v;
vector<long double> x;

long double hat(long long b1, long long k1, long long b2, long long k2)
{
    return 1.0 * (b2 - b1 + 0.0) / (k1 - k2 + 0.0);
}

void ave(int j)
{
    if (!v.empty() && p[v.back()] == p[j])
        return;
    while (!v.empty() && p[v.back()] == p[j])
    {
        v.pop_back();
        if (!x.empty())
            x.pop_back();
    }
    while (v.size() >= 2)
    {
        long double x1 = hat(dp[v.back()] - p[v.back()] * p[v.back()], p[v.back()], dp[j] - p[j] * p[j], p[j]);
        if (x1 > x.back())
            break;
        v.pop_back();
        x.pop_back();
    }
    if (v.empty())
    {
        v.push_back(j);
        return;
    }
    long double x1 = hat(dp[v.back()] - p[v.back()] * p[v.back()], p[v.back()], dp[j] - p[j] * p[j], p[j]);
    x.push_back(x1);
    v.push_back(j);
}

int byn(int i)
{
    int l = 0, r = x.size() - 1;
    while ((r - l) > 3)
    {
        int m = (l + r) / 2;
        if (p[i] >= x[m] && v[m + 1] < i)
            l = m;
        else
            r = m;
    }
    for (int m = r; m >= l; --m)
    {
        if (p[i] >= x[m] && v[m + 1] < i)
            return v[m + 1];
    }
    return v[0];
}

int main()
{
    //freopen("input.txt", "r", stdin);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    for (int i = 1; i <= n; ++i)
        p[i] = p[i - 1] + a[i];

    for (int i = 1; i <= n; ++i)
        ave(i);
    for (int k = 1; k <= m; ++k)
    {
        for (int i = k + 1; i <= n; ++i)
        {
            int j = byn(i);
            ndp[i] = dp[j] - p[j] * p[j] + p[j] * p[i];
            pp[i][k] = j;
        }
        for (int i = k + 1; i <= n; ++i)
            dp[i] = ndp[i];
        v.clear();
        x.clear();
        for (int i = k + 1; i <= n; ++i)
            ave(i);
    }
    cout << dp[n] << endl;
    int i = n;
    for (int k = m; k > 0; --k)
    {
        cout << pp[i][k] << ' ';
        i = pp[i][k];
    }
    cout << endl;
    return 0;
}
#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...