[BZOJ 1112] [POI2008] 砖块Klo 【区间K大】
题目链接:BZOJ - 1112
题目分析
枚举每一个长度为k的连续区间,求出这个区间的最优答案,更新全局答案。
可以发现,这个区间的所有柱子最终都变成这k个数的中位数时最优,那么我们就需要查询这个区间的中位数了。
找到中位数之后,我们还应该求出这个区间内小于中位数的数的和,大于中位数的数的和,从而求出操作步数。
这些需要求的值可以用线段树或平衡树来写,我写的是线段树,但是实际上这是一道POI的题目,在MAIN上的空间限制只有35MB,线段树应该是不行的。
因为平衡树只需要 O(n) 空间,所以平衡树才是正解。
代码
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio> using namespace std; const int MaxN = 100000 + 5, MaxNode = 100000 * 20 + 15, MN = 1000000 + 5; typedef long long LL; int n, k, Index, Root;
int A[MaxN], T[MaxNode], Son[MaxNode][2]; const LL INF = 999999999999; LL Ans;
LL Sum[MaxNode]; inline LL gmin(LL a, LL b) {return a < b ? a : b;} inline void Read(int &Num)
{
char c; c = getchar();
while (c < '0' || c > '9') c = getchar();
Num = c - '0'; c = getchar();
while (c >= '0' && c <= '9')
{
Num = Num * 10 + c - '0';
c = getchar();
}
} void Add(int &x, int s, int t, int Pos, int Num)
{
if (x == 0) x = ++Index;
T[x] += Num;
Sum[x] += (LL)Pos * (LL)Num;
if (s == t) return;
int m = (s + t) >> 1;
if (Pos <= m) Add(Son[x][0], s, m, Pos, Num);
else Add(Son[x][1], m + 1, t, Pos, Num);
} int Kth(int x, int s, int t, int k)
{
if (s == t) return s;
int ret, m = (s + t) >> 1;
if (T[Son[x][0]] >= k) ret = Kth(Son[x][0], s, m, k);
else ret = Kth(Son[x][1], m + 1, t, k - T[Son[x][0]]);
return ret;
} LL GetSum(int x, int s, int t, int l, int r)
{
if (l <= s && r >= t) return Sum[x];
int m = (s + t) >> 1;
LL ret = 0ll;
if (l <= m && Son[x][0]) ret += GetSum(Son[x][0], s, m, l, r);
if (r >= m + 1 && Son[x][1]) ret += GetSum(Son[x][1], m + 1, t, l, r);
return ret;
} int GetNum(int x, int s, int t, int l, int r)
{
if (l <= s && r >= t) return T[x];
int m = (s + t) >> 1;
int ret = 0;
if (l <= m && Son[x][0]) ret += GetNum(Son[x][0], s, m, l, r);
if (r >= m + 1 && Son[x][1]) ret += GetNum(Son[x][1], m + 1, t, l, r);
return ret;
} int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i) Read(A[i]);
Root = Index = 0;
A[0] = 0;
for (int i = 0; i <= k - 1; ++i) Add(Root, 0, MN, A[i], 1);
Ans = INF;
int t = k / 2 + 1, Temp;
LL Now;
for (int i = k; i <= n; ++i)
{
Add(Root, 0, MN, A[i - k], -1);
Add(Root, 0, MN, A[i], 1);
Temp = Kth(Root, 0, MN, t);
Now = (LL)GetNum(Root, 0, MN, 0, Temp - 1) * (LL)Temp - GetSum(Root, 0, MN, 0, Temp - 1);
Now += GetSum(Root, 0, MN, Temp + 1, MN) - (LL)GetNum(Root, 0, MN, Temp + 1, MN) * (LL)Temp;
Ans = gmin(Ans, Now);
}
printf("%lld\n", Ans);
return 0;
}
[BZOJ 1112] [POI2008] 砖块Klo 【区间K大】的更多相关文章
- BZOJ 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1736 Solved: 606[Submit][Statu ...
- BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1112 [题目大意] 给出一个数列,对于一个操作,你可以对一个数+1,或者一个数-1, ...
- 线段树 || BZOJ 1112: [POI2008]砖块Klo
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1112 题解: 希望有连续K柱的高度是一样的,就先把1~K的数扔进线段树(线段树的下标就是数值 ...
- BZOJ 1112: [POI2008]砖块Klo Splay + 性质分析
Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...
- bzoj 1112: [POI2008]砖块Klo【对顶堆】
priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...
- 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 ...
- BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树
之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池 ...
- [Bzoj1112][POI2008]砖块Klo(splay)
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2353 Solved: 831[Submit][Statu ...
随机推荐
- chrome下老是弹出网页显示 true
事实上这个问题是chrome下安装了一些插件的原因,一般来说是安装迅雷插件会出现这个问题,删除迅雷插件就好了.
- the Linux Kernel: Traffic Control, Shaping and QoS
−Table of Contents Journey to the Center of the Linux Kernel: Traffic Control, Shaping and QoS 1 Int ...
- MYSQL学习笔记2--mysql 静态和动态plugin
mysql源码编译 .cmke 安装 yum install cmake .依赖的库下载机安装: yum -y install gcc* gcc-c++* autoconf* automake* zl ...
- MYSQL参数学习---------------- 张碧池
http://pottievil.com/category/mysql/mysql%E5%8F%82%E6%95%B0/
- QuaZip实现多文件打包
项目需求: 在Goldenfarm客户端中当用户选择了本地场景文件,并进行本地场景文件分析后会产生分析结果,分析结果主要包括:贴图纹理.可渲染层等,其中贴图纹理指出了在场景文件中使用到的贴图或其它文件 ...
- telnet的使用
1.要打开 telnet 不是内部或外部 命令 解决方案: 程序添加删除功能,添加即可 或法二 C:\WINDOWS\system32\telnet.exe (或用C:\WINDOWS\system3 ...
- SpringMVC项目学习1_web.xml
最近接触的所有项目都是SpringMVC+ajax的项目,因此以一个项目为例学习下. --------------------------------------------------------- ...
- Android 自定义View修炼-自定义可动画展开收缩View的实现
有时候需要点击一个view可以动画展开和收缩折叠一个View这样的效果,这样就可以直接自定义View来实现. 本例中,采用继承FrameLayout来实现自定义的ExpandView.下面将详细介绍各 ...
- 【原】window上安装elasticserach
[window上安装elasticserach] 系统环境:2008R2 x64测试安装用的服务器IP:192.168.12.52elasticsearch版本:2.3.4JDK版本:jdk 1.8. ...
- Install-User.ps1
Install-User.ps1 function Install-User { param( [Parameter()] [string]$ComputerName = $env:computern ...