【BZOJ1112】[POI2008]砖块Klo Treap
【BZOJ1112】[POI2008]砖块Klo
Description
N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任务.
Input
第一行给出N,K. (1 ≤ k ≤ n ≤ 100000), 下面N行,每行代表这柱砖的高度.0 ≤ hi ≤ 1000000
Output
最小的动作次数
Sample Input
3
9
2
3
1
Sample Output
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的更多相关文章
- [BZOJ1112] [POI2008] 砖块Klo (treap)
Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次 ...
- [BZOJ1112][POI2008]砖块Klo
[BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...
- [Bzoj1112][POI2008]砖块Klo(splay)
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2353 Solved: 831[Submit][Statu ...
- BZOJ1112[POI2008]砖块Klo——非旋转treap
题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...
- 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo
枚举长度为m的所有段,尝试用中位数更新答案. 所以需要数据结构,支持查询k大,以及大于/小于 k大值 的数的和. 平衡树.权值线段树.权值分块什么的随便呢. #include<cstdio> ...
- 【主席树】bzoj1112: [POI2008]砖块Klo
数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...
- BZOJ 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1736 Solved: 606[Submit][Statu ...
- 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1245 Solved: 426[Submit][Statu ...
- [bzoj1112][POI2008]砖块Klo_非旋转Treap
砖块Klo bzoj-1112 POI-2008 题目大意:$N$柱砖,希望有连续$K$柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖 ...
随机推荐
- 修改Linux文件句柄限制
1. 添加ulimit -HSn 655350 到/etc/profile 2. 配置生效 source /etc/profile 修改linux文件句柄数 分类: LINUX 2010-09 ...
- golang自定义返回error
在开发过程中, 标准库返回的error内容已经无法满足我们的需要时,发现builtin.go中error是一个interface, type error interface { Error() ...
- .net提供的5种request-response方法一
.net提供了三种基本方法和两种底层方法来发送http请求和接收http响应,通过这些方法,我们可以模仿在浏览器地址栏输入URL地址访问网页的方法.我们发送http请求,接收服务器返回的响应(通常就是 ...
- 在hibernate中查询单个对象的方法,get()、load()、
查询单个对象可以直接通过Session对象来做到,其中session这个对象提过了2种获得单个对象的方法,一个是get方法和load方法,我去看这个两个方法的时候发现这两个方法的参数是一样的,使用方式 ...
- WPF查找子控件和父控件方法
一.查找某种类型的子控件,并返回一个List集合 public List<T> GetChildObjects<T>(DependencyObject obj, Type ty ...
- e680. 使三元色图像变明变暗
This example demonstrates how to brighten or darken an RGB buffered image by scaling the red, green, ...
- 【Java面试题】27 多线程笔试面试概念问答
第一题:线程的基本概念.线程的基本状态及状态之间的关系? 线程,有时称为轻量级进程,是CPU使用的基本单元:它由线程ID.程序计数器.寄存器集合和堆栈组成.它与属于同一进程的其他线程共享其代码段.数据 ...
- 将Excel中读取的科学计数法表示的Double数据转换为对应的字符串
已在SegmentFault提问,目前没有答案,自行实现如下: private static String getRealNumOfScientificNotation(String doubleSt ...
- 设置div滚动条
这个是很常见的一个任务了,基本是通过CSS去实现滚动条. 滚动条 设置是否显示滚动条主要是在CSS中设置下列的属性: 代码如下: overflow:visible|auto|hidden|scroll ...
- idea 新建项目 文件名都是红色的处理办法
原因是当前的project用了版本控制器 所以这个project下面所有的项目都加入版本控制器里了,所以项目文件和名称都是红色的 简单文字叙述解决办法 file-->settings--> ...