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:从仓库中拿出一块砖,放到另 ...
随机推荐
- div+css兼容 ie6_ie7_ie8_ie9_ie10和FireFox_Chrome等浏览器方法
1.div的垂直居中问题 vertical-align:middle; 将行距增加到和整个DIV一样高 line-height:200px; 然后插入文字,就垂直居中了.缺点是要控制内容不要换行 ...
- BZOJ 1588: [HNOI2002]营业额统计
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 14396 Solved: 5521[Submit][Sta ...
- [LINK]OpenResty
http://openresty.org/ http://www.tuicool.com/articles/M3yI3y http://www.oschina.net/question/28_6046 ...
- 10 个迅速提升你 Git 水平的提示
1. Git自动补全 假使你使用命令行工具运行Git命令,那么每次手动输入各种命令是一件很令人厌烦的事情.为了解决这个问题,你可以启用Git的自动补全功能,完成这项工作仅需要几分钟. 为了得到这个脚本 ...
- CUDA1-hello world
电脑配置:windows7 sp1 64bit + CUDA6.5 + GeForce GTX780 Ti 显卡中的GPU因为多核可以处理很多相同的操作,相比较来说cpu就像个健全的手,什么活都能干 ...
- 【干货分享】JPager.Net MVC超好用轻量级分页控件
JPager.Net MVC好用的轻量级分页控件,好用到你无法想象,轻量到你无法想象. JPager.Net MVC好用的轻量级分页控件,实现非常简单,使用也非常简单. JPager.Net M ...
- Bootstrap系列 -- 8. 代码显示
一. Bootstrap中的代码块 代码块一般在博客中使用的较多,比较博客园中提供的贴代码. 在Bootstrap中提供了三种形式的代码显示 1. 使用<code></code> ...
- SQL2008R2 不支持用该后端版本设计数据库关系图或表
向下不兼容. 要么安装SQL2012,要么把SQL2012数据库通过脚本转成2008
- C# WinForm捕获全局异常
网上找的C# WinForm全局异常捕获方法,代码如下: static class Program { /// <summary> /// 应用程序的主入口点. /// </summ ...
- 前端框架——AmazeUI学习
AmazeUI官网: http://amazeui.org/ 前后台模板下载:链接:链接:http://pan.baidu.com/s/1c2uVfk0 密码:zuva 十大前端框架参考链接:http ...