【BZOJ1112】[POI2008]砖块Klo

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

原题还要求输出结束状态时,每柱砖的高度.本题略去.

题解:我们先只考虑一段区间,如果我们想花最小的费用使所有权值相等,那么一定是将他们全变成这段区间的中位数,那么我们只需要从左往右平移这段区间,那么就将问题转变成了动态求某段区间内的中位数,用Treap完全可以搞定。

那么如何得到答案呢?我们可以将答案表示成这样:

ans=(所有比mid大的元素的和 - mid * 比mid大的元素的个数)+(mid * 比mid小的元素的个数 - 所有比mid小的元素的和)

这个我们可以在递归求mid的时候顺便就求出来,具体细节什么的还是自己YY一下吧

别忘了开long long

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,m,tot,root,mid;
ll ans,minn;
int k[maxn],ch[maxn][2];
ll h[maxn],v[maxn],siz[maxn],s[maxn],sum[maxn],cnt[maxn];
void pushup(int x)
{
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+v[x]*cnt[x];
}
void rotate(int &x,int d)
{
int y=ch[x][d];
ch[x][d]=ch[y][d^1],ch[y][d^1]=x;
pushup(x),pushup(y);
x=y;
}
void insert(int &x,ll y)
{
if(!x)
{
x=++tot,sum[x]=v[x]=y,siz[x]=cnt[x]=1,k[x]=rand();
return ;
}
siz[x]++;
if(v[x]==y)
{
cnt[x]++,sum[x]+=y;
return ;
}
int d=(y>v[x]);
insert(ch[x][d],y);
if(k[ch[x][d]]>k[x]) rotate(x,d);
pushup(x);
}
void del(int &x,ll y)
{
if(v[x]==y)
{
if(cnt[x]>1)
{
cnt[x]--,siz[x]--,sum[x]-=y;
return ;
}
if(ch[x][0]*ch[x][1]==0) x=(ch[x][0]^ch[x][1]);
else rotate(x,(k[ch[x][0]]<k[ch[x][1]])),del(x,y);
return;
}
siz[x]--,sum[x]-=y;
if(v[x]>y) del(ch[x][0],y);
else del(ch[x][1],y);
}
void query(int x,int y)
{
if(siz[ch[x][0]]>=y) ans+=sum[ch[x][1]]+v[x]*cnt[x],query(ch[x][0],y);
else if(siz[ch[x][0]]+cnt[x]<y) ans-=sum[ch[x][0]]+v[x]*cnt[x],query(ch[x][1],y-siz[ch[x][0]]-cnt[x]);
else ans+=sum[ch[x][1]]-sum[ch[x][0]]+v[x]*(2*siz[ch[x][0]]+cnt[x]-2*y+(m&1));
}
int main()
{
srand(233333);
int i;
scanf("%d%d",&n,&m);
for(i=1;i<m;i++) scanf("%lld",&h[i]),s[i]=s[i-1]+h[i],insert(root,h[i]);
minn=1ll<<60;
for(;i<=n;i++)
{
scanf("%d",&h[i]),s[i]=s[i-1]+h[i],insert(root,h[i]);
if(i>m) del(root,h[i-m]);
ans=0,query(root,m+1>>1);
minn=min(minn,ans);
}
printf("%lld",minn);
return 0;
}

【BZOJ1112】[POI2008]砖块Klo Treap的更多相关文章

  1. [BZOJ1112] [POI2008] 砖块Klo (treap)

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

  2. [BZOJ1112][POI2008]砖块Klo

    [BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...

  3. [Bzoj1112][POI2008]砖块Klo(splay)

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2353  Solved: 831[Submit][Statu ...

  4. BZOJ1112[POI2008]砖块Klo——非旋转treap

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

  5. 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo

    枚举长度为m的所有段,尝试用中位数更新答案. 所以需要数据结构,支持查询k大,以及大于/小于 k大值 的数的和. 平衡树.权值线段树.权值分块什么的随便呢. #include<cstdio> ...

  6. 【主席树】bzoj1112: [POI2008]砖块Klo

    数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...

  7. BZOJ 1112: [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1736  Solved: 606[Submit][Statu ...

  8. 1112: [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1245  Solved: 426[Submit][Statu ...

  9. [bzoj1112][POI2008]砖块Klo_非旋转Treap

    砖块Klo bzoj-1112 POI-2008 题目大意:$N$柱砖,希望有连续$K$柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖 ...

随机推荐

  1. Ajax-jQuery_Ajax_实例 ($.ajax、$.post、$.get)

    Jquery在异步提交方面封装的很好,直接用AJAX非常麻烦,Jquery大大简化了我们的操作,不用考虑浏览器的诧异了. 推荐一篇不错的jQuery Ajax 实例文章,忘记了可以去看看, 地址为:h ...

  2. jQuery实现布局高宽自适应

    在页面布局(layout)时经常是上左右的框架布局并且需要宽.高度的自适应,div+css是无法实现(*hegz:div+css其实是可以实现的,利用jQuery比较容易实现浏览器的兼容性),所以需要 ...

  3. selenium测试(Java)--多表单切换(十二)

    采用下面的例子来编写用例 <!DOCTYPE html> <html> <head> <meta http-equiv="content-type& ...

  4. python + opencv: kalman 跟踪

    之前博文中讲解过kalman滤波的原理和应用,这里用一个跟踪鼠标的例程来演示怎么在opencv里用自带的kalman函数进行目标跟踪,文章的内容对做图像跟踪有借鉴意义.文章主要是网络资源进行整理和简单 ...

  5. Android startActivityForResult 回传数据

    一个activity打开新的activity,新的activity关闭之后,返回数据.原来的activity要接收返回的数据,在开启新的activity时,就需要调用startActivityForR ...

  6. (转)Invalidate、RedrawWindow与UpdateWindow的区别

     一:什么时候才会发生重绘窗口的消息? 当需要更新或重新绘制窗口的外观时,应用程序就会发送WM_PAINT消息.对窗口进行重新绘制. 二:Invalidate() -- RedrawWindow() ...

  7. R语言绘图布局

    在R语言中,par 函数可以设置图形边距,其中oma 参数设置outer margin, mar 参数设置margin, 这些边距有什么不同呢,通过box函数可以直观的看到 box 默认在当前图形绘制 ...

  8. perl chomp 函数的真正作用

    之前一直以为chomp函数只是去掉字符串末尾的\n, 但是今天写程序遇到一个bug,最后的原因就处在chomp上: 读取fasta文件,内容如下: >1 ATGCTAGCTACGTACGTACG ...

  9. windows环境下mongodb下载、安装和使用总结

    一.首先安装mongodb 1.下载地址:http://dl.mongodb.org/dl/win32/x86_64 2.解压缩到自己想要安装的目录,比如d:\mongodb 3.创建文件夹d:\mo ...

  10. ubuntu-15.04-desktop-i386.iso:ubuntu-15.04-desktop-i386:安装Oracle11gR2

    ubuntu 桌面版的安装不介绍. 如何安装oracle:核心步骤和关键点. ln -sf /bin/bash /bin/sh ln -sf /usr/bin/basename /bin/basena ...