BZOJ 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1736 Solved: 606
[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
分析
对于一段区间,可以知道将高度改为中位数是最优的,因此我们需要做的是维护一个区间的中位数,以及小于中位数的数字之和和大于中位数的数字之和,这个可以平衡树,可以树状数组+二分查找,或者是线段树上二分,甚至是STL set,做法太多……
代码
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #define ri register int #define lim 10000000 char *c = new char[lim]; template <class T>
void read(T &x)
{
x = ; while (*c < '')++c; while (*c >= '')
x = x* + *c++ - '';
} template <class T>
void Min(T &a, T b)
{
if (a > b)a = b;
} template <class T>
void Max(T &a, T b)
{
if (a < b)a = b;
} #define N 1000005 int n, m;
int h[N]; struct node
{
int lt, rt, cnt;
long long sum;
}tree[N * ]; void build(int p, int l, int r)
{
node &t = tree[p]; t.lt = l;
t.rt = r; t.cnt = t.sum = ; if (l ^ r)
{
int mid = (l + r) >> ; build(p << , l, mid);
build(p << | , mid + , r);
}
} void insert(int p, int pos, int val1, int val2)
{
node &t = tree[p]; t.cnt += val1;
t.sum += val2; if (t.lt ^ t.rt)
{
int mid = (t.lt + t.rt) >> ; if (pos <= mid)
insert(p << , pos, val1, val2);
else
insert(p << | , pos, val1, val2);
}
} int query1(int p, int rank)
{
node &t = tree[p]; if (t.lt == t.rt)return t.lt; if (tree[p << ].cnt >= rank)
return query1(p << , rank);
else
return query1(p << | , rank - tree[p << ].cnt);
} long long query2(int p, int l, int r)
{
if (l > r)return 0LL; node &t = tree[p]; if (l == t.lt && r == t.rt)
return t.sum; int mid = (t.lt + t.rt) >> ; if (r <= mid)
return query2(p << , l, r);
if (l > mid)
return query2(p << | , l, r);
return query2(p << , l, mid) + query2(p << | , mid + , r);
} int query3(int p, int l, int r)
{
if (l > r)return 0LL; node &t = tree[p]; if (l == t.lt && r == t.rt)
return t.cnt; int mid = (t.lt + t.rt) >> ; if (r <= mid)
return query3(p << , l, r);
if (l > mid)
return query3(p << | , l, r);
return query3(p << , l, mid) + query3(p << | , mid + , r);
} signed main(void)
{
fread(c, , lim, stdin); read(n);
read(m); ri maxi = ;
ri mini = N; for (ri i = ; i <= n; ++i)
{
read(h[i]); Min(mini, h[i]);
Max(maxi, h[i]);
} build(, , N); for (ri i = ; i < m; ++i)
insert(, h[i], , h[i]); int d = (m + ) >> ; long long ans = 1e18 + ; for (ri i = m; i <= n; ++i)
{
insert(, h[i], , h[i]); {
int mid = d; long long q = query1(, mid), res = 0LL; long long lc = query3(, , q - );
long long rc = query3(, q + , N); res += lc*q - query2(, , q - );
res += query2(, q + , N) - rc*q; Min(ans, res);
} insert(, h[i - m + ], -, -h[i - m + ]);
} printf("%lld\n", ans);
}
BZOJ_1112.cpp
@Author: YouSiki
BZOJ 1112: [POI2008]砖块Klo的更多相关文章
- [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了哈哈哈 ------------ ...
- 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1245 Solved: 426[Submit][Statu ...
- [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:从仓库中拿出一块砖,放到另 ...
随机推荐
- Linux下误删除后的恢复操作(ext3/ext4)
Linux是作为一个多用户.多任务的操作系统,文件一旦被删除是难以恢复的.尽管删除命令只是在文件节点中作删除标记,并不真正清除文件内容,但是其他用户和一些有写盘动作的进程会很快覆盖这些数据.在日常工程 ...
- 浅谈python web框架中的orm设计
看了一下廖雪峰的那个web框架,其实就是封装了web.py,请求使用异步并将aiomysql做为MySQL数据库提供了异步IO的驱动,前端部分则整合了jinja.其中最难的应该是orm部分了. 下面是 ...
- python实现一个图灵机器人
这标题就是个噱头...其实用的别人的接口,就是这货. 下面是代码: # -*- coding: utf-8 -*- import urllib,urllib2 import sys import js ...
- smarty foreach循环
1,smarty foreach1,单纯的数组array(1000,2000,3000),使用foreach(from = $array item=foo){$foo}2,键值对数组<ul> ...
- html代码中显示系统时间
可以显示系统的静态时间和动态时间 1,静态时间 <script type="text/javascript"> var myDate = new Date(); doc ...
- 恢复Reflector反编译后资源文件的办法
反编译问题: 1.路径问题:如果遇到了Path.Combine,有错误改下即可 2.资源文件问题: 在Reflector下,对左边的资源管理窗口的Resources文件夹下的资源文件,进行右键点击,选 ...
- vs 2005 thread 无法调试
两种办法:1.打开项目属性,在“Debug”一项里,把“Enable the Visual Studio hosting process”前的钩去掉.这个方法不是好办法.2.打开计算机管理,在服务里将 ...
- HTML5+JS 《五子飞》游戏实现(六)鼠标响应与多重选择
上一章我们提到了如果有多条线上的棋子可以被吃掉,那么游戏需要提示用户,让用户选择吃哪条线上的.另外因为是网页游戏,所以一定要实现鼠标单击棋子可以进行操作. 当鼠标移动棋子上面后,切换鼠标指针为手形,移 ...
- PHP中JSON的跨域调用
主调文件index.html <script type="text/javascript"> function getProfile(str) { var arr = ...
- Web软件安全攻击