Files
SH-Quizzes/ACMOJ-2147.cpp
2024-04-18 18:38:55 +08:00

66 lines
2.1 KiB
C++

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL;
typedef long double LDB;
const int kMaxN = 510;
const int kMaxT = 4e6 + 100 + 10;
int n, m;
int t[kMaxN];
int bucket[kMaxT], bucket_tot[kMaxT], max_t;
LL f[kMaxT], bucket_t_sum[kMaxT];
int Q[kMaxT], QL, QR;
inline LL GetY(int id) { return f[id] + bucket_t_sum[id]; }
int main() {
#ifdef local
freopen("pro.in", "r", stdin);
#endif
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &t[i]);
bucket[t[i]]++;
max_t = t[i] > max_t ? t[i] : max_t;
}
bucket_tot[0] = bucket[0];
for (int i = 1; i <= max_t + m - 1; i++) {
bucket_tot[i] = bucket_tot[i - 1] + bucket[i];
bucket_t_sum[i] = bucket_t_sum[i - 1] + i * (LL)bucket[i];
}
QL = 0;
QR = -1;
int pend_cur = 0;
for (int i = 0; i <= max_t + m - 1; i++) {
f[i] = bucket_tot[i] * (LL)i - bucket_t_sum[i];
// for (int j = 0; j + m <= i; j++) {
// f[i] = min(f[i], f[j] + (bucket_tot[i] - bucket_tot[j]) * (LL)i -
// bucket_t_sum[i] + bucket_t_sum[j]);
// // f[j] + bucket_t_sum[j] =i*bucket_tot[j]+ f[i] - bucket_tot[i]*i +
// // bucket_t_sum[i]
// }
while (pend_cur + m <= i) {
while (QR - QL + 1 >= 2 &&
(bucket_tot[pend_cur] - bucket_tot[Q[QR - 1]]) *
(GetY(Q[QR]) - GetY(Q[QR - 1])) -
(GetY(pend_cur) - GetY(Q[QR - 1])) *
(bucket_tot[Q[QR]] - bucket_tot[Q[QR - 1]]) >=
0)
QR--;
Q[++QR] = pend_cur;
pend_cur++;
}
while (QR - QL + 1 >= 2 &&
GetY(Q[QL + 1]) - GetY(Q[QL]) <=
i * (LL)(bucket_tot[Q[QL + 1]] - bucket_tot[Q[QL]]))
QL++;
if (QL <= QR)
f[i] = min(f[i], f[Q[QL]] + (bucket_tot[i] - bucket_tot[Q[QL]]) * (LL)i -
bucket_t_sum[i] + bucket_t_sum[Q[QL]]);
// printf("f(%d)=%lld\n", i, f[i]);
}
LL res = 0x3f3f3f3f3f3f3f3f;
for (int i = max_t; i <= max_t + m - 1; i++) res = min(res, f[i]);
printf("%lld\n", res);
return 0;
}