码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1112: [POI2008]砖块Klo

时间:2018-04-16 18:20:43      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:+=   geo   shu   script   连续   div   tps   仓库   ++   

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
 
 
今天考试时把这东西做出来还是挺开心的!
狗脑思考可得这东西还是中位数最佳。。
然后拍树状数组
 
代码如下:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
int lowbit(int x){return x&-x;}
ll c[2100000],s[2100000];
void change(ll x,ll d)
{
    while(x<=1100000)
    {
        c[x]+=d;
        x+=lowbit(x);
    }
}
ll getshuliang(ll x)
{
    ll sum=0;
    while(x!=0)
    {
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
ll getpaiming(ll sum)
{
    ll x=0,now=0;
    for(ll i=(1ll<<22);i;i>>=1)
    {
        if(x+i<=1100000&&now+c[x+i]<sum)
        now+=c[x+i],x+=i;
    }
    ++x;
    return x;
}
void gai(ll x,ll d)
{
    while(x<=1100000)
    {
        s[x]+=d;
        x+=lowbit(x);
    }
}
ll getsum(ll x)
{
    ll sum=0ll;
    while(x)
    {
        sum+=s[x];
        x-=lowbit(x);
    }
    return sum;
}
ll dd[1100000];
int n,k;
ll a[110000];
int main()
{
    freopen("akc.in","r",stdin);
    freopen("akc.out","w",stdout);
    ll ans=1ll<<61;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]++;
    int pos=1;
    for(int i=1;i<k;i++)dd[a[i]]++,change(a[i],1),gai(a[i],a[i]);
    for(int i=k;i<=n;i++)
    {
        change(a[i],1),gai(a[i],a[i]);dd[a[i]]++;
        ll X;
        if(k%2==1)X=getpaiming(k/2+1);
        else X=(getpaiming(k/2)+getpaiming(k/2+1))/2;

        ll sum1=getsum(X-1),sum2=getsum(getpaiming(k))-sum1-dd[X]*X;
        ll geshu1=getshuliang(X-1),geshu2=k-geshu1-dd[X];
        
        ans=min(ans,X*geshu1-sum1+sum2-X*geshu2);
        if(ans==0ll)break;
        change(a[pos],-1),gai(a[pos],-a[pos]);dd[a[pos]]--;
        pos++;
    }
    printf("%lld\n",ans);
    return 0;
}

by_lmy

BZOJ1112: [POI2008]砖块Klo

标签:+=   geo   shu   script   连续   div   tps   仓库   ++   

原文地址:https://www.cnblogs.com/MT-LI/p/8856761.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!