# [bzoj1112][树状数组]砖块Klo

Description

N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了.
2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任务.

Input

Output

Sample Input

5 3

3

9

2

3

1

Sample Output

2

HINT

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL a[1110000],mmax;
int s[1110000],n,K;
int lowbit(int x){return x&-x;}
void chs(int x,int c){while(x<=mmax){s[x]+=c;x+=lowbit(x);}}
void cha(int x,LL c){while(x<=mmax){a[x]+=c;x+=lowbit(x);}}
LL findsum(int x){LL ret=0;while(x>=1){ret+=a[x];x-=lowbit(x);}return ret;}
int findall(int x){int ret=0;while(x>=1){ret+=s[x];x-=lowbit(x);}return ret;}
LL h[1110000];
int main()
{
scanf("%d%d",&n,&K);
mmax=0;
for(int i=1;i<=n;i++)scanf("%lld",&h[i]),h[i]++,mmax=max(mmax,h[i]);
for(int i=1;i<K;i++)cha(h[i],h[i]),chs(h[i],1);
LL owb=1000000000000000000;
int mid=K/2+1;
for(int i=K;i<=n;i++)
{
cha(h[i],h[i]);chs(h[i],1);
if(i-K>=1)cha(h[i-K],-h[i-K]),chs(h[i-K],-1);
int cnt=0,ans=0;
for(int j=(1<<21);j;j>>=1)if(ans+s[cnt+j]<mid && cnt+j<=mmax)ans+=s[cnt+j],cnt+=j;
cnt++;
int sum=findall(cnt-1);
LL tmp=(LL)cnt*sum-findsum(cnt-1);
sum=findall(mmax)-findall(cnt);
tmp+=findsum(mmax)-findsum(cnt)-(LL)cnt*sum;
owb=min(owb,tmp);
}
printf("%lld\n",owb);
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120