1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1245 Solved: 426
[Submit][Status][Discuss]
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
原题还要求输出结束状态时,每柱砖的高度.本题略去.
Source
题解:(呵呵呵我会说我逗到了用Splay做这题的地步么= =)
首先,看这道题,对于某个高度序列而言,很明显将所有高度都变为中位数代价最小
我觉得任何一个数竞党都该知道怎么样可以让下列式子值最小——
\( \sum_{i=1}^{N} \left | x-x_i \right | \)
其中,\( x_1 \leq x_2 \leq x_3 ... \leq x_N \)
显然,当N为奇数时, \( x=x_\frac{N+1}{2} \)
当N为偶数时, \( x_\frac{N}{2} \leq x \leq x_\frac{N+2}{2} \)
然后接下来讨论怎么实现——我们需要一棵平衡树,可以加入和删除值,可以查询指定排名的数位置(用来找中位数),还得可以快速求出当前序列中比中位数大的各个数之和,以及比它小的之和,这样子就很明显需要维护子树大小(用于排名),然后还得维护子树和,然后我为了偷懒就直接来了个splay,每次将中位数splay上来,然后两边的不就是我们要的两边和嘛,然后该怎么办怎么办,别的没了
/**************************************************************
Problem:
User: HansBug
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ var
i,j,k,m,n,head:longint;
l,ans:int64;
lef,rig,b:array[..] of longint;
a,c:array[..] of int64;
procedure rt(var x:longint);inline;
var f,l:longint;
begin
if (x=) or (lef[x]=) then exit;
b[lef[x]]:=b[x];b[x]:=b[rig[lef[x]]]+b[rig[x]]+;
c[lef[x]]:=c[x];c[x]:=c[rig[lef[x]]]+c[rig[x]]+a[x];
f:=x;l:=lef[x];
lef[f]:=rig[l];
rig[l]:=f;
x:=l;
end;
procedure lt(var x:longint);inline;
var f,r:longint;
begin
if (x=) or (rig[x]=) then exit;
b[rig[x]]:=b[x];b[x]:=b[lef[rig[x]]]+b[lef[x]]+;
c[rig[x]]:=c[x];c[x]:=c[lef[rig[x]]]+c[lef[x]]+a[x];
f:=x;r:=rig[x];
rig[f]:=lef[r];
lef[r]:=f;
x:=r;
end;
procedure splay(var x:longint;y:longint);inline;
begin
if (x=) or (y=) then exit;
if y=(b[lef[x]]+) then exit;
if y<(b[lef[x]]+) then
begin
if (b[lef[lef[x]]]+)=y then rt(x) else
if y<(b[lef[lef[x]]]+) then
begin
splay(lef[lef[x]],y);
rt(x);rt(x);
end
else
begin
splay(rig[lef[x]],y-b[lef[lef[x]]]-);
lt(lef[x]);rt(x);
end;
end
else
begin
y:=y--b[lef[x]];
if y=(b[lef[rig[x]]]+) then lt(x) else
if y<(b[lef[rig[x]]]+) then
begin
splay(lef[rig[x]],y);
rt(rig[x]);lt(x);
end
else
begin
splay(rig[rig[x]],y--b[lef[rig[x]]]);
lt(x);lt(x);
end;
end;
end;
procedure ins(var x:longint;y:longint);inline;
begin
if x= then
begin
x:=y;
exit;
end;
if a[y]<=a[x] then
begin
ins(lef[x],y);
c[x]:=c[lef[x]]+c[rig[x]]+a[x];
b[x]:=b[lef[x]]+b[rig[x]]+;
end
else
begin
ins(rig[x],y);
c[x]:=c[lef[x]]+c[rig[x]]+a[x];
b[x]:=b[lef[x]]+b[rig[x]]+;
end;
end;
function getrank(x,y:longint):longint;inline;
begin
if x= then exit(-);
if a[x]=y then exit(b[lef[x]]+);
if y<a[x] then exit(getrank(lef[x],y)) else exit(b[lef[x]]++getrank(rig[x],y));
end;
procedure init(x:longint);inline;
begin
ins(head,x);
splay(head,random(b[head])+);
end;
procedure kill(x:longint);inline;
begin
if x= then
begin
splay(head,);
dec(c[head],c[lef[head]]);
dec(b[head]);
lef[head]:=;
end
else if x=b[head] then
begin
splay(head,b[head]-);
dec(c[head],c[rig[head]]);
dec(b[head]);
rig[head]:=;
end
else begin
splay(head,x+);
splay(lef[head],x-);
dec(c[head],c[rig[lef[head]]]);dec(b[head]);
dec(c[lef[head]],c[rig[lef[head]]]);dec(b[lef[head]]);
rig[lef[head]]:=;
end;
end;
begin
readln(n,m);randomize;
if m<= then
begin
writeln();
halt;
end;
for i:= to n do
begin
readln(a[i]);
c[i]:=a[i];b[i]:=;
lef[i]:=;rig[i]:=;
end;
head:=;ans:=maxlongint*maxlongint;
for i:= to m do init(i);
for i:= to n-m+ do
begin
splay(head,(m+) div );
l:=;
if lef[head]<> then inc(l,a[head]*b[lef[head]]-c[lef[head]]);
if rig[head]<> then inc(l,c[rig[head]]-a[head]*b[rig[head]]);
if l<ans then ans:=l;
if i=(n-m+) then break;
kill(getrank(head,a[i]));
init(i+m);
end;
writeln(ans);
readln;
end.
1112: [POI2008]砖块Klo的更多相关文章
- BZOJ 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1736 Solved: 606[Submit][Statu ...
- [BZOJ 1112] [POI2008] 砖块Klo 【区间K大】
题目链接:BZOJ - 1112 题目分析 枚举每一个长度为k的连续区间,求出这个区间的最优答案,更新全局答案. 可以发现,这个区间的所有柱子最终都变成这k个数的中位数时最优,那么我们就需要查询这个区 ...
- 线段树 || BZOJ 1112: [POI2008]砖块Klo
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1112 题解: 希望有连续K柱的高度是一样的,就先把1~K的数扔进线段树(线段树的下标就是数值 ...
- BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1112 [题目大意] 给出一个数列,对于一个操作,你可以对一个数+1,或者一个数-1, ...
- bzoj 1112: [POI2008]砖块Klo【对顶堆】
priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...
- BZOJ 1112: [POI2008]砖块Klo Splay + 性质分析
Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...
- BZOJ 1112: [POI2008]砖块Klo1112( BST )
枚举每个长度为k的区间, 然后用平衡树找中位数进行判断, 时间复杂度O(nlogn). 早上起来精神状态不太好...连平衡树都不太会写了...果断去看了会儿番然后就A了哈哈哈 ------------ ...
- [Bzoj1112][POI2008]砖块Klo(splay)
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2353 Solved: 831[Submit][Statu ...
- [BZOJ1112][POI2008]砖块Klo
[BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...
随机推荐
- HTML 颜色
HTML 颜色 HTML 颜色由红色.绿色.蓝色混合而成. 颜色值 HTML 颜色由一个十六进制符号来定义,这个符号由红色.绿色和蓝色的值组成(RGB). 种颜色的最小值是0(十六进制:#00).最大 ...
- Spring classPath:用法
http://blog.csdn.net/xing_sky/article/details/8228305 参考文章地址: http://hi.baidu.com/huahua035/item/ac8 ...
- EntityFramework Core解决并发详解
前言 对过年已经无感,不过还是有很多闲暇时间来学学东西,这一点是极好的,好了,本节我们来讲讲EntityFramewoek Core中的并发问题. 话题(EntityFramework Core并发) ...
- 【JAVA笔记】JAVA后端实现统一扫码支付:微信篇
最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用 ...
- 开发团队在TFS中使用Git Repository (二)
使用Git作分支时,仅仅是对提交历史记录的一个引用,创建分支成本非常低,分支的切换快且简单.在分支管理方面,相对其他的版本管理工具,Git可谓是一骑绝尘. 开发过程中,我们可以针对任何的大小功能进行分 ...
- 史上最全的synchronized解释
首先:推荐使用synchronized(obj)这种方法体的使用方式,一个类里面建议尽量使用单一的同步方法,多种方法混用,维护成本太大. 其次:关于java5.0新增的ReenTrantLock方法: ...
- 【ci框架基础】之部署百度编辑器
在ci框架下加载编辑器,现在复习下内容.我的框架文件名称为ci 1.下载百度编辑器ueditor,http://ueditor.baidu.com/ 一般情况下下载ubuilder版即可,并将uedi ...
- 类似qq空间的无限回复怎么实现??
在开发网站的时候遇到这样一个问题,下面是自己的一些思路: 1.把数据库简单的设计出来了 2.这是自己写的简单的例子 3.图表形式 1: 1.发表一篇文章 2: 2给1评论 3: 3给2评论 2 ...
- C++学习的心路历程之心理障碍
断断续续的C++学习已经过了1年多了,可是,我还是没有迈出可以自如输出写点什么的那一步.甚至我因为这个老是怀疑自己的智商,我是真心想学懂,因为这个关系到我的就业,直接关系到我的饭碗.我是十分的着急,可 ...
- 在 Linux OpenVPN 服务端吊销客户端证书
OpenVPN服务器与 VPN 客户端之间的身份验证, 主要是通过证书来进行的.有时我们需要禁止某个用户连接 VPN 服务器,则将其证书吊销即可.要吊销(Revoke) OpenVPN 客户端证书, ...