题目链接:传送门
题解:
显然每次取中位数,暴力枚举区间,用一个平衡树维护就好啦
ps: splay插入时忘记旋转,T得飞起
//by sdfzchy
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define pa t[x].fa
#define ls t[x].ch[0]
#define rs t[x].ch[1]
using namespace std;
typedef long long LL;
const int inf=(1<<30),N=100010,mod=1e9+7;
int n,m,a[N],k;
inline int in()
{
char tmp=getchar();
int res=0,f=1;
while((tmp<'0'||tmp>'9')&&tmp!='-')tmp=getchar();
if(tmp=='-') f=-1,tmp=getchar();
while(tmp>='0'&&tmp<='9') res=(res<<1)+(res<<3)+(tmp^48),tmp=getchar();
return res*f;
}
int root;
LL ans=inf;
struct node
{
int ch[2],siz,fa,cnt;
LL val,sum;
}t[N];
inline int gi(int x) {return t[pa].ch[1]==x;}
inline void upd(int x)
{
t[x].siz=t[ls].siz+t[rs].siz+t[x].cnt;
t[x].sum=t[ls].sum+t[rs].sum+t[x].cnt*t[x].val;
}
void rot(int x)
{
int f=pa,g=t[pa].fa,o=gi(x);
if(g) t[g].ch[gi(f)]=x;t[x].fa=g;
t[f].ch[o]=t[x].ch[!o];t[t[x].ch[!o]].fa=f;
t[x].ch[!o]=f;t[f].fa=x;
upd(f),upd(x);
}
void splay(int x,int tar)
{
for(;pa!=tar;rot(x))
if(t[pa].fa!=tar)
rot((gi(x)==gi(pa))?pa:x);
if(!tar) root=x;
}
int cnt;
void newnode(int &x,int val)
{
x=++cnt;
t[x].ch[0]=t[x].ch[1]=0;
t[x].siz=t[x].cnt=1;
t[x].val=t[x].sum=val;
}
void ins(int &x,int val,int fa)
{
if(!x) {newnode(x,val);pa=fa;splay(x,0);return;}
t[x].siz++;
if(t[x].val==val) {t[x].cnt++;t[x].sum+=val;return;}
if(val>t[x].val) ins(rs,val,x);
else ins(ls,val,x);
upd(x);
}
int find(int val)
{
int x=root;
while(x)
{
if(t[x].val==val) break;
if(val>t[x].val) x=rs;
else x=ls;
}
if(x) splay(x,0);
return x;
}
void del(int val)
{
int x=find(val);
if(t[x].cnt>1) {t[x].cnt--;t[x].siz--;t[x].sum-=val;return;}
if(!ls&&!rs) root=0;
if(!ls) {root=rs;t[rs].fa=0;return;}
if(!rs) {root=ls;t[ls].fa=0;return;}
int pos=t[x].ch[0];
while(t[pos].ch[1]) pos=t[pos].ch[1];
splay(pos,x);
t[pos].ch[1]=rs;t[rs].fa=pos;t[pos].fa=0;root=pos;
upd(pos);
}
int kth(int kk)
{
int x=root;
while(x)
{
if(t[ls].siz>=kk) x=ls;
else if(t[ls].siz+t[x].cnt<kk) kk-=t[ls].siz+t[x].cnt,x=rs;
else return x;
}
}
void ga()
{
int x=kth((k+1)>>1);
splay(x,0);
ans=min(ans,abs(t[x].val*t[ls].siz-t[ls].sum)+abs(t[x].val*t[rs].siz-t[rs].sum));
}
int main()
{
ans=10000000000000000ll;
n=in(),k=in();
for(int i=1;i<=n;i++) a[i]=in();
for(int i=1;i<=k;i++) ins(root,a[i],0);
ga();
for(int i=k+1;i<=n;i++)
{
del(a[i-k]);
ins(root,a[i],0);
ga();
}
printf("%lld",ans);
return 0;
}