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

13人阅读 评论(1) 收藏 举报
分类:

Description

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

Input

第一行给出N,K. (1 ≤ k ≤ n ≤ 100000), 下面N行,每行代表这柱砖的高度.0 ≤ hi ≤ 1000000

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;
}
查看评论

bzoj1112 POI2008 砖块Klo 树状数组

fuxey必须%。。。 树状数组的话,其实就是相当于滑动窗口,然后用树状数组维护当前中位数,总和用前缀和搞一下,就可以直接算了。#include #include #include #include...
  • qq_35866453
  • qq_35866453
  • 2017-04-27 09:25:44
  • 136

BZOJ 1112 [POI2008]砖块Klo Treap

BZOJ 1112 [POI2008]砖块Klo Treap
  • wzq_QwQ
  • wzq_QwQ
  • 2015-09-14 20:17:03
  • 1070

bzoj-1112 砖块Klo

题意: 给出一个长度为n的数列,现要将其连续k个数变成一样的; 每次可以对一个数+1或-1,问最小操作次数; 1 题解: 感觉是一道好题吧; 首先有这样一个结论:将这些数置为中位数...
  • ww140142
  • ww140142
  • 2015-09-15 07:42:17
  • 1338

bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)

把一个区间的数都变成一个数,显然都变成中位数需要的次数最少,而次数就是后k/2的数的和-前k/2的数的和,因此原问题就是求区间中位数。区间中位数可以平衡树来搞,也可以用stl水过hh。先把1…k排序,...
  • Icefox_zhx
  • Icefox_zhx
  • 2017-11-09 16:30:10
  • 109

Bzoj1112:[POI2008]砖块Klo:splay

题目链接:1112:[POI2008]砖块Klo 原题目是要输出最终高度的,代码中有体现 显然一段区间都变成某个数且代价最小,那么就变成中位数 所以我们维护中位数即可,上splay 一不小心把树建反成...
  • qq_34025203
  • qq_34025203
  • 2016-04-08 10:07:59
  • 307

BZOJ1112: [POI2008]砖块Klo

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1112 题目大意:N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱...
  • qq_29206999
  • qq_29206999
  • 2016-08-15 10:02:29
  • 148

BZOJ1112 - [POI2008]砖块Klo

网上题解都是平衡树?
  • VicJiao
  • VicJiao
  • 2017-11-03 17:02:11
  • 641

bzoj1112【poi2008】砖块klo

平衡树
  • AaronGZK
  • AaronGZK
  • 2015-11-24 23:54:17
  • 1005

【POI2008】【BZOJ1112】砖块Klo

DescriptionN柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数...
  • CreationAugust
  • CreationAugust
  • 2016-02-04 09:48:54
  • 463

[bzoj1112][POI2008]砖块Klo

http://www.lydsy.com/JudgeOnline/problem.php?id=1112 每次可以使任意一柱砖高度+1或-1,代价为1 求使任意一个长度为K的区间内砖的高度相同的最...
  • YZHYZHYZH3
  • YZHYZHYZH3
  • 2017-09-28 11:53:29
  • 87
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 3万+
    积分: 3299
    排名: 1万+
    博客专栏
    最新评论