제출 #208857

#제출 시각아이디문제언어결과실행 시간메모리
208857baohiep수열 (APIO14_sequence)C++14
100 / 100
674 ms85860 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 5, K = 205;

struct Line {
  int id;
  ll a, b;
  Line(int _id, ll _a, ll _b): id(_id), a(_a), b(_b) {}

  ll calc(ll x) {
    return a * x + b;
  }
};

int n, k, a[N], trace[N][K];
ll sum[N], dp[N], pre[N];
vector<Line> dq;

double intersect(const Line &p, const Line &q) {
  return (double)(p.b - q.b) / (double)(q.a - p.a);
}

bool overlap(const Line &p1, const Line &p2, const Line &p3) {
  return intersect(p1, p3) <= intersect(p1, p2);
  //return (p2.a - p1.a) * (p1.b - p3.b) <= (p3.a - p1.a) * (p1.b - p2.b);
}

int main() {
  ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  cin >> n >> k;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
    sum[i] = sum[i - 1] + a[i];
  }

  for (int j = 1; j <= k; ++j) {
    int seen = 0;
    dq.clear();
    fill(dp + 1, dp + 1 + n, 0);
    for (int i = 1; i <= n; ++i) {
      while (seen + 1 < (int)dq.size() && dq[seen].calc(sum[i]) <= dq[seen + 1].calc(sum[i])) ++seen;
      if (seen < (int)dq.size()) {
        dp[i] = dq[seen].calc(sum[i]);
        trace[i][j] = dq[seen].id;
      }

      Line newLine = Line(i, sum[i], pre[i] - sum[i] * sum[i]);
      while (dq.size() > 1 && overlap(dq[(int)dq.size() - 2], dq.back(), newLine)) dq.pop_back();
      dq.push_back(newLine);

      pre[i] = dp[i];
    }
  }

  vector<int> pos;
  int cur = n;
  while (k) pos.emplace_back(cur = trace[cur][k--]);
  reverse(pos.begin(), pos.end());

  cout << dp[n] << "\n";
  for (int x: pos) cout << x << " ";
  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...