http://www.lydsy.com/JudgeOnline/problem.php?id=1112
每次可以使任意一柱砖高度+1或-1,代价为1
求使任意一个长度为K的区间内砖的高度相同的最小代价
只要动态维护中位数就可以了…
维护中位数可以用两个堆…
n1为堆1大小,n2为堆2大小
s1为堆1和,s2为堆2和
每次移动区间后维护abs(n1,n2)<2就能保证中位数的准确性了……
然后当前区间答案为n1*mid-s1+s2-n2*mid
#include <cstdio>
#include <queue>
using namespace std;
priority_queue <int> h1;
priority_queue <int,vector<int>,greater<int> > h2;
#define N 100005
#define ll long long
inline int read()
{
char ch=getchar();
int x=0;
while (ch<'0' || ch>'9') ch=getchar();
while ('0'<=ch && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x;
}
inline ll abs(ll a) {return a>0?a:-a;}
ll s1=0LL,s2=0LL;
int a[N],tot1[1000005],tot2[1000005];
int n,m,middle,n1,n2;
inline void up1()
{
while (!h1.empty() && !tot1[h1.top()]) h1.pop();
}
inline void up2()
{
while (!h2.empty() && !tot2[h2.top()]) h2.pop();
}
int main()
{
n=read(),m=read();
if (m==1) return puts("0");
for (int i=1;i<=n;++i) a[i]=read();
for (int i=1;i<=m;++i) h1.push(a[i]),++tot1[a[i]],s1+=a[i],++n1;
for (int i=1;(i<<1)<=m;++i) s1-=h1.top(),--tot1[h1.top()],--n1,h2.push(h1.top()),++tot2[h1.top()],s2+=h1.top(),++n2,h1.pop();
middle=h1.top();s1-=h1.top(),--n1,--tot1[h1.top()],h1.pop();
ll ans=(1LL<<60);
ans=min(ans,(ll)(n1)*middle-s1+s2-(ll)(n2)*middle);
for (int i=2;i<=n-m+1;++i)
{
if (a[i+m-1]<=middle)
{
h1.push(a[i+m-1]);
++tot1[a[i+m-1]];
s1+=a[i+m-1];
++n1;
}else
{
h2.push(a[i+m-1]);
++tot2[a[i+m-1]];
s2+=a[i+m-1];
++n2;
}
if (tot1[a[i-1]])
{
--tot1[a[i-1]];
s1-=a[i-1];
--n1;
}else
if (tot2[a[i-1]])
{
--tot2[a[i-1]];
s2-=a[i-1];
--n2;
}else
{
if (n1>n2) up1(),middle=h1.top(),--n1,--tot1[h1.top()],s1-=h1.top(),h1.pop();
else up2(),middle=h2.top(),--n2,--tot2[h2.top()],s2-=h2.top(),h2.pop();
}
if (abs(n1-n2)>1){
if (n1<n2)
{
++n1,--n2;
h1.push(middle);
++tot1[middle];
s1+=middle;
up2();
middle=h2.top();h2.pop();
--tot2[middle];
s2-=middle;
}else
{
--n1,++n2;
h2.push(middle);
++tot2[middle];
s2+=middle;
up1();
middle=h1.top();h1.pop();
--tot1[middle];
s1-=middle;
}}
ans=min(ans,(ll)(n1)*middle-s1+s2-(ll)(n2)*middle);
}
printf("%lld\n",ans);
}
Orz用树状数组,treap,主席树过的dalao…
Orz w_yqts