【题目链接】
最终高度一定是中位数,然后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; }