题目链接: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大】的更多相关文章

  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(可持久化线段树)

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

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

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

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

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

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

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

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

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

  7. 1112: [POI2008]砖块Klo

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

  8. BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树

    之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池 ...

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

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

随机推荐

  1. [MySQL] MySQL的自己主动化安装部署

    有过MySQL运维的人应该都清楚,线上的MySQL一般都採用源代码编译,由于这样才干够依据企业的各自须要选择要编译的功能,尽管MySQL的源代码编译挺简单的,可是试想一下,假设你有几百台server同 ...

  2. TabHost 两种使用方法 直接让一个Activity 继承TabActivity 和 利用findViwById()方法取得TagHost组件

    第一种,TabActivity 解决方案 下面建立的布局文件,它包含多个标签的显示组件 <?xml version="1.0" encoding="utf-8&qu ...

  3. Spark1.0 安装

    1.下载Scala wget  http://www.scala-lang.org/files/archive/scala-2.10.3.tgz tar xvzf scala-2.10.3.tgz - ...

  4. HDU ACM 1392 Surround the Trees-&gt;凸包

    分析:直接求出凸包.再算边长就可以. 另外仅仅有一个点时为0.00单独处理,两个点直接为距离也单独处理. #include<iostream> #include<cmath> ...

  5. getline和get的区别

    #include<iostream> #include<fstream> #include<cstring> using namespace std; int ma ...

  6. Linux 确定系统glibc版本

    在shell中,可以直接运行glibc共享库文件获取glibc版本,CentOS下执行: /lib/libc.so. 输出为: GNU C Library stable release version ...

  7. SAMBA用户访问指定的目录

    指定某个用户访问一个特定的共享文件夹sfx 用户可以访问abc目录 别的用户不可以访问abc目录 先创建一个用户命令useradd sfx 创建一个smbpasswd用户 在创建这个用户时要先创建一个 ...

  8. javascript moveTo() 函数

    moveTo-- 移动窗体左上角到相对于屏幕左上角的(x,y)点,当使用负数做为参数时会吧窗体移出屏幕的可视区域 moveTo,中文"移动到"的意思 引用网址:http://www ...

  9. VS2010无法打开CSS问题

    安装了VS2010的SP1补丁后,发现打开css文件时出现下面问题: 一点击css文件就弹出:未能完成操作.未指定的错误.无法正常进入. [解决方法]安装最新Web Standards Update补 ...

  10. AndroidStudio字体主题样式分享

    最近慢慢在从eclipse往AndroidStudio习惯,但总觉得AS的默认字体颜色看的不舒服,便花了些时间将字体颜色样式改成了和原来类似的.以下是效果图. 这里是下载地址http://downlo ...