题目描述

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

输入

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

输出

最小的动作次数

样例输入

5 3
3
9
2
3
1

样例输出

2
 
考虑对于只有$k$个数的序列的最优解,显然是将所有数都变成中位数(因为如果变成的数比中位数小或者大都会有多于一半的数要改变)。
那么我们只需要维护出有$k$个连续数的序列,求出中位数并维护比中位数大的数的和及比中位数小的数的和即可得到这$k$个数的最优解,用平衡树维护即可。
对于$n$个数的序列只需要每次对连续$k$个数维护信息并求最优解然后取最小值即可。每次将第$i$个数删除,再将第$i+k$个数插入。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll ans;
int n,k;
int s[100010];
struct treap
{
treap *ls,*rs;
int size;
int val;
int rnd;
ll sum;
treap(){}
treap(treap *son,int v)
{
ls=rs=son;
size=1;
val=v;
sum=1ll*v;
rnd=rand();
}
void pushup()
{
sum=ls->sum+rs->sum+val;
size=ls->size+rs->size+1;
}
}tr[100010],nil;
typedef treap* node;
node root,null,cnt;
node a,b,c;
inline void init()
{
nil=treap(NULL,0);
null=&nil;
null->ls=null->rs=null;
null->size=0;
root=null;
cnt=tr;
}
inline node build(int v)
{
*cnt=treap(null,v);
return cnt++;
}
inline node merge(node x,node y)
{
if(x==null)
{
return y;
}
if(y==null)
{
return x;
}
if(x->rnd<y->rnd)
{
x->rs=merge(x->rs,y);
x->pushup();
return x;
}
else
{
y->ls=merge(x,y->ls);
y->pushup();
return y;
}
}
inline void split1(node rt,node &x,node &y,int k)
{
if(rt==null)
{
x=y=null;
return ;
}
if(rt->ls->size>=k)
{
y=rt;
split1(rt->ls,x,y->ls,k);
}
else
{
x=rt;
split1(rt->rs,x->rs,y,k-1-rt->ls->size);
}
rt->pushup();
}
inline void split2(node rt,node &x,node &y,int k)
{
if(rt==null)
{
x=y=null;
return ;
}
if(rt->val>=k)
{
y=rt;
split2(rt->ls,x,y->ls,k);
}
else
{
x=rt;
split2(rt->rs,x->rs,y,k);
}
rt->pushup();
}
inline void query()
{
split1(root,a,b,k/2);
split1(b,b,c,1);
ll res=1ll*a->size*b->val-a->sum;
res+=c->sum-1ll*c->size*b->val;
ans=min(res,ans);
root=merge(merge(a,b),c);
}
int main()
{
srand(12378);
scanf("%d%d",&n,&k);
ans=1ll<<60;
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
}
for(int i=1;i<=k;i++)
{
split2(root,a,b,s[i]);
root=merge(merge(a,build(s[i])),b);
}
query();
for(int i=k+1;i<=n;i++)
{
split2(root,a,b,s[i-k]);
split1(b,b,c,1);
root=merge(a,c);
split2(root,a,b,s[i]);
root=merge(merge(a,build(s[i])),b);
query();
}
printf("%lld",ans);
}

BZOJ1112[POI2008]砖块Klo——非旋转treap的更多相关文章

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

    砖块Klo bzoj-1112 POI-2008 题目大意:$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)

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

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

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

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

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

  7. 【BZOJ1112】[POI2008]砖块Klo Treap

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

  8. BZOJ 1112: [POI2008]砖块Klo

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

  9. 1112: [POI2008]砖块Klo

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

随机推荐

  1. 文件的基本管理和XFS文件系统备份恢复

    4.1 Linux系统目录结构和相对/绝对路径 4.1.1系统目录结构 在WIN系统中,查看文件先进入相应的盘符,然后进入文件目录 在WIN中,它是多根  c:\    d:\   e:\ Linux ...

  2. 关于单链表的增删改查方法的递归实现(JAVA语言实现)

    因为在学习数据结构,准备把java的集合框架底层源码,好好的过一遍,所以先按照自己的想法把单链表的类给写出来了; 写该类的目的: 1.练习递归 2.为深入理解java集合框架底层源码打好基础 学习的视 ...

  3. setTimeout与setInterval的区别浅析

    在网页制作动态效果时,一定会遇到某些需求,要求某段程序等待多时时间后再开始执行,就像在我们的生活中一样,待会儿再开始做一件事.在JavaScript中主要通过定时器实现此类需求,本文将对定时器做一个概 ...

  4. U813.0操作员功能权限和数据权限的设置

    操作员的权限有功能权限.数据权限.金额权限. 1. 给操作员设置功能权限,操作员才能进入系统进行相关业务操作. Admin用户登录无法修改账套,但可以新建.引入.输出.Demo用户每次只能进入一个账套 ...

  5. MySQL Error Number 1005 Can’t create table(Errno:150)

    mysql数据库1005错误解决方法 MySQL Error Number 1005 Can’t create table ‘.\mydb\#sql-328_45.frm’ (errno: 150) ...

  6. SQLServer创建用户自定义数据库用户

    创建用户自定义数据库用户注意事项 如果已忽略 FOR LOGIN,则新的数据库用户将被映射到同名的SQL Server登录名. 默认架构将是服务器为此数据库用户解析对象名时将搜索的第一个架构. 除非另 ...

  7. 用addRoutes实现动态路由

    原文转自前端路上,转载请注明出处. 之前在基于Vue实现后台系统权限控制一文中提到路由权限的实现思路,因为不喜欢在每次路由跳转的before钩子里做判断,所以在初始化Vue实例前对路由做了筛选,再用实 ...

  8. socket.io 出现的WebSocket is closed before the connection is established

    WebSocket is closed before the connection is established 最近socket.io是挺流行的,幼麟棋牌和一些好的开源项目也使用这个框架,在搭建其平 ...

  9. 如何在element-UI 组件的change事件中传递自定义参数

    以select为例,如果select写在循环里,触发change事件时可能不只需要传递被选中项的值,还要传递index过去,来改变同一循环中的其他标签的状态. 下面这样写是无效的: @change=& ...

  10. Python 爬虫 之 阅读呼叫转移(一)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/jcjc918/article/details/37533073     你是否苦恼于网上无法下载的& ...