66 lines
2.1 KiB
C++
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;
|
|
} |