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

5 3
3
9
2
3
1

Sample Output

2

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的更多相关文章

  1. BZOJ 1112: [POI2008]砖块Klo

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

  2. [BZOJ 1112] [POI2008] 砖块Klo 【区间K大】

    题目链接:BZOJ - 1112 题目分析 枚举每一个长度为k的连续区间,求出这个区间的最优答案,更新全局答案. 可以发现,这个区间的所有柱子最终都变成这k个数的中位数时最优,那么我们就需要查询这个区 ...

  3. 线段树 || BZOJ 1112: [POI2008]砖块Klo

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1112 题解: 希望有连续K柱的高度是一样的,就先把1~K的数扔进线段树(线段树的下标就是数值 ...

  4. BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1112 [题目大意] 给出一个数列,对于一个操作,你可以对一个数+1,或者一个数-1, ...

  5. bzoj 1112: [POI2008]砖块Klo【对顶堆】

    priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...

  6. BZOJ 1112: [POI2008]砖块Klo Splay + 性质分析

    Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...

  7. BZOJ 1112: [POI2008]砖块Klo1112( BST )

    枚举每个长度为k的区间, 然后用平衡树找中位数进行判断, 时间复杂度O(nlogn). 早上起来精神状态不太好...连平衡树都不太会写了...果断去看了会儿番然后就A了哈哈哈 ------------ ...

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

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

  9. [BZOJ1112][POI2008]砖块Klo

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

随机推荐

  1. 创建第一个Android应用程序 HelloWorld

    按照博客的进程,今天应该进行程序编写啦,下面让我们开写一个简单的HelloWorld程序. 提示:这里对于如何使用Eclipse创建一个Android程序就不多讲啦,不会的同学可以去查阅相关文档. 程 ...

  2. 数据库基础-INDEX

    http://m.oschina.net/blog/10314 一.引言 对数据库索引的关注从未淡出我的们的讨论,那么数据库索引是什么样的?聚集索引与非聚集索引有什么不同?希望本文对各位同仁有一定的帮 ...

  3. HTML 样式- CSS

    如何使用CSS CSS 是在 HTML 4 开始使用的,是为了更好的渲染HTML元素而引入的. CSS 可以通过以下方式添加到HTML中: 内联样式- 在HTML元素中使用"style&qu ...

  4. Python爬虫基础

    前言 Python非常适合用来开发网页爬虫,理由如下: 1.抓取网页本身的接口 相比与其他静态编程语言,如java,c#,c++,python抓取网页文档的接口更简洁:相比其他动态脚本语言,如perl ...

  5. 转载:MyEclipse安装插件的几种方法

    地址:http://www.cnblogs.com/pharen/archive/2012/02/08/2343342.html 本文讲解MyEclipse(MyEclipse10)的三种方法,以SV ...

  6. iOS核心笔记—源代码管理工具-SVN

    源代码管理工具-SVN 一. 源代码管理工具概述 1. 源代码管理工具的作用? > 能追踪一个项目从诞生一直到定案的过程 > 记录一个项目的所有内容变化,无限制返回 > 查看特定版本 ...

  7. view里面的tableview顶部被view的导航栏盖住了的问题

    在你要显示的控制器的viewDidLoad中添加代码 self.edgesForExtendedLayout = UIRectEdgeNone; 另外记住tableView要遵循代理cell才能显示. ...

  8. 如何使用Babel将ES6转码为ES5?

    一.前言: 当我们还在沉迷于ES5的时候,殊不知ES6早就已经发布几年了.时代在进步,WEB前端技术也在日新月异,是时候做些改变了! ECMAScript 6(ES6)的发展速度非常之快,但现代浏览器 ...

  9. next_permutation(全排列算法)

    STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation.首先我们必须了解什么是"下一个"排列组合,什么是"前 ...

  10. shell脚本编程常识

    (这些往往是经常用到,但是各种网络上的材料都语焉不详的东西,个人认为比较有用) 七种文件类型 d            目录                                       ...