제출 #1166733

#제출 시각아이디문제언어결과실행 시간메모리
1166733Kerim수열 (APIO14_sequence)C++17
0 / 100
0 ms324 KiB
#include "bits/stdc++.h"
using namespace std;
 
#define ll long long
const ll INF=-LLONG_MAX;
bool Q;

struct Line {
    mutable ll k, m, p;
    int ind;
    bool operator<(const Line &o) const {
        return Q ? p < o.p : k < o.k;
    }
};
 
struct LineContainer : multiset<Line> {
    const ll inf = LLONG_MAX;
    ll div(ll a, ll b) {
        return a / b-((a ^ b) < 0 && a % b);
    }
    bool isect(iterator x, iterator y) {
        if (y == end()) { 
            x->p = inf; 
            return false; 
        }
        if (x->k == y->k)
            x->p = (x->m > y->m ? inf : -inf);
        else
            x->p = div(y->m-x->m, x->k-y->k);
        return x->p >= y->p;
    }
    void add(ll k, ll m, int ind) {
        auto z = insert({k, m, 0, ind}), y = z++, x = y;
        while (isect(y, z))
            z = erase(z);
        if (x != begin() && isect(--x, y))
            isect(x, y = erase(y));
        while ((y = x) != begin() && (--x)->p >= y->p)
            isect(x, erase(y));
    }
    pair<ll, int> query(ll x) {
        if (empty())
            return {-inf, -2};
        Q = true;
        auto l = *lower_bound({0, 0, x});
        Q = false;
        return {l.k * x + l.m, l.ind};
    }
};
 
int main(){
    int n, k;
    scanf("%d%d", &n, &k);
    vector<int> v(n+1), p(n+1);
    for(int i = 1; i <= n; ++i){
        int x;
        scanf("%d", &x), v[i]=x, p[i]=p[i-1]+x;
    }
    vector<vector<pair<ll, int>>> dp(n+1, vector<pair<ll, int>>(k+1, {INF, -1}));
    for(int i = 0; i <= n; i++)
        dp[i][0]={0, 0};
    for(int k1 = 1; k1 <= k; ++k1){
        LineContainer cht;
        for(int i = 1; i <= n; ++i){
            if(dp[i-1][k1-1].first!=INF)
                cht.add(p[i-1], dp[i-1][k1-1].first-p[i-1]*1ll*p[i-1], i-1);
            dp[i][k1]=cht.query(p[i]);
        }
    }
    printf("%lld\n", dp[n][k].first);
    vector<int> indices;
    int ns = n, ks = k;
    while (ks > 0){
        if (ns != n)
            indices.push_back(ns);
        ns = dp[ns][ks].second;
        ks -= 1;
    }
    indices.push_back(1);
    reverse(indices.begin(), indices.end());
    for (auto ind: indices)
        printf("%d ", ind);
    puts("");
    return 0;
}

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

sequence.cpp: In function 'int main()':
sequence.cpp:53:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   53 |     scanf("%d%d", &n, &k);
      |     ~~~~~^~~~~~~~~~~~~~~~
sequence.cpp:57:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   57 |         scanf("%d", &x), v[i]=x, p[i]=p[i-1]+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...