最终高度一定是中位数,然后Splay维护一下就可以了。
答案会炸int。一开始只给加法加了LL,最后意识到先算的是乘法,所以给乘法加了LL就AC了。
/* Pigonometry */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100005;
const LL linf = 1LL << 60;
int n, m, h[maxn];
int pre[maxn], son[maxn][2], val[maxn], size[maxn];
LL sum[maxn], ans;
int root, tot1, tot2, sta[maxn];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline void pushup(int x) {
int l = son[x][0], r = son[x][1];
sum[x] = sum[l] + val[x] + sum[r];
size[x] = size[l] + 1 + size[r];
}
inline void newnode(int &x, int f, int c) {
x = tot2 ? sta[tot2--] : ++tot1;
son[x][0] = son[x][1] = 0;
pre[x] = f;
val[x] = sum[x] = c;
size[x] = 1;
}
inline void init() {
root = tot1 = tot2 = 0;
son[0][0] = son[0][1] = val[0] = sum[0] = pre[0] = size[0] = 0;
}
inline void rotate(int x) {
int y = pre[x], z = pre[y], type = son[y][1] == x;
pre[son[y][type] = son[x][!type]] = y;
pre[x] = z;
if(z) son[z][son[z][1] == y] = x;
pre[son[x][!type] = y] = x;
pushup(y); pushup(x);
}
inline void splay(int x, int goal) {
while(pre[x] != goal) {
int y = pre[x], z = pre[y];
if(z == goal) rotate(x);
else if(son[z][1] == y ^ son[y][1] == x) rotate(x), rotate(x);
else rotate(y), rotate(x);
}
if(!goal) root = x;
}
inline int find(int k) {
int x = root;
while(k != size[son[x][0]] + 1)
if(k <= size[son[x][0]]) x = son[x][0];
else k -= size[son[x][0]] + 1, x = son[x][1];
return x;
}
inline int getmin(int x) {
for(; son[x][0]; x = son[x][0]);
return x;
}
inline int getmax(int x) {
for(; son[x][1]; x = son[x][1]);
return x;
}
inline void insert(int c) {
if(root == 0) {
newnode(root, 0, c);
pushup(root);
return;
}
int x = root;
for(; son[x][c > val[x]]; x = son[x][c > val[x]]);
newnode(son[x][c > val[x]], x, c);
splay(son[x][c > val[x]], 0);
}
inline void del(int c) {
int x = root;
for(; val[x] != c; x = son[x][c > val[x]]);
splay(x, 0);
int l = getmax(son[x][0]), r = getmin(son[x][1]);
if(l == 0) {
root = son[x][1];
pre[son[x][1]] = 0;
}
else if(r == 0) {
root = son[x][0];
pre[son[x][0]] = 0;
}
else {
splay(l, 0); splay(r, l);
son[r][0] = 0;
}
pre[x] = son[x][0] = son[x][1] = val[x] = sum[x] = size[x] = 0;
sta[++tot2] = x;
if(r) pushup(r);
if(l) pushup(l);
}
inline void update() {
int x = find(m);
splay(x, 0);
ans = min(ans, (LL)val[x] * size[son[x][0]] - sum[son[x][0]] + sum[son[x][1]] - (LL)val[x] * size[son[x][1]]);
}
int main() {
n = iread(); int k = iread(); m = (k + 1) >> 1;
for(int i = 1; i <= n; i++) h[i] = iread();
init();
ans = linf;
for(int i = 1; i <= k; i++) insert(h[i]);
for(int i = k + 1; i <= n; i++) {
update();
del(h[i - k]);
insert(h[i]);
}
update();
printf("%lld\n", ans);
return 0;
}