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:从仓库中拿出一块砖,放到另 ... 
随机推荐
- win7配置自己的IIS服务器亲自做的图文很详细
			跟人网站爱好初学者必看的win7系统配置自己的IIS,可以在你自己的电脑上配置网站服务器发不到网上,下面就跟着我的步骤一起做吧100%成功. 步骤/方法 点击开始-------控制面板这个就是 ... 
- Google中Gson的使用解析json数据-------学习篇
			之前写过一篇Gson解析json数据的基本应用,这里不多说,直接上例子. 有兴趣的可以先阅读下之前那篇,这里附上链接: http://www.cnblogs.com/Ant-soldier/p/632 ... 
- POJ2187(旋转卡壳)
			Beauty Contest Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 35459 Accepted: 10978 ... 
- CodeForces 721A
			A. One-dimensional Japanese Crossword time limit per test:1 second memory limit per test:256 megabyt ... 
- com.atomikos.icatch.HeurHazardException: Heuristic Exception
			com.atomikos.icatch.HeurHazardException: Heuristic Exception: 删除Tomcat bin文件夹下的spring.loglog4j.appe ... 
- 微信面试题-获取元素的最终background-color
			一.题目 用JS代码求出页面上一个元素的最终的background-color,不考虑IE浏览器,不考虑元素float情况. 二.题目解析 1.考察底层JavaScript基础 前端开发,日常最 ... 
- vs2010 入门程序
			#include <stdio.h> int main(){ printf("hello world!\n"); getchar(); //此处避免执行完程序自动退出 ... 
- Linux 6.4    partprobe出现warning问题
			今天在给服务器做LVM的时候(服务器的系统是CentOS 6.3),用fdisk分区之后,用w写入分区表的时候,就提示Command (m for help): wThe partition tabl ... 
- 使用批处理根据项目工程文件生成Nuget包并发布(支持.NET Core)
			最近在使用之前自己编写的批处理给.NET Core项目打包时出问题了,发现之前的脚本根本不适用了,折腾了半天,总算解决了.因此在这里分享下经验,并且奉上整理好的脚本. Nuget包这里就不多介绍了,需 ... 
- int与integer的区别(基本数据类型与引用数据类型)
			一.先说说int与integer的区别 int 是基本数据类型,默认值为0,不需要进行实例化 integer 是引用数据类型,是int的封装类型,默认值为null,创建该类型需要进行实例化. 基本数据 ... 
