题目链接: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;
}

  

转载于:https://www.cnblogs.com/JoeFan/p/4324577.html

[BZOJ 1112] [POI2008] 砖块Klo 【区间K大】相关推荐

  1. 1112: [POI2008]砖块Klo

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

  2. [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2910 Solved: 1026 [Submit][Stat ...

  3. bzoj1112[POI2008]砖块Klo*

    bzoj1112[POI2008]砖块Klo 题意: N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:丢掉某柱砖的一块砖.给某柱加上一块砖,现在希望用最小次数的动作完成任务.N≤1 ...

  4. [POI2008] 砖块Klo

    洛谷 P3466 传送门 bzoj 1112 传送门 用treap维护一段长为k的区间即可. 先把1~k-1的都插入treap. 然后从k到n进行如下操作: 插入一个,计算,删除一个. 用到一个结论: ...

  5. BZOJ1112 - [POI2008]砖块Klo

    原题链接 题意简述 给出一个n(n≤105)n(n \leq 10^5)个数的序列a(max{a}≤106)a(max\{a\}\leq10^6),每次给一个数+1/-1.求使得序列中存在连续k(k≤ ...

  6. 【主席树】bzoj1112: [POI2008]砖块Klo

    数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...

  7. BZOJ1112: [POI2008]砖块Klo

    Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次 ...

  8. hdu 2665(主席树查询区间k大值)

    先贴我自己写的代码做模板虽然跟原博主没什么两样.(一开始空间开的4*maxn,交到hdu上一直TLE很奇怪) #include<bits/stdc++.h> using namespace ...

  9. BZOJ1112[POI2008]砖块Klo——非旋转treap

    题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...

最新文章

  1. 中农植保-昆虫进化与基因组诚聘博后及科研助理-三亚中国农业大学研究院
  2. 测试mktime和localtime_r性能及优化方法
  3. 全国计算机等级考试二级教程——公共基础知识(2013年版)pdf,全国计算机等级考试2级教程:公共基础知识(2013年版)...
  4. 【bzoj4385】[POI2015]Wilcze doły
  5. ionic助手 v1.9.0 一键式开发环境工具(告别命令行,超强功能)
  6. 布局管理器android,Android课程---布局管理器之相对布局(一)
  7. 工作271:打开弹出框调用当前页面接口
  8. 如何配置Smarty模板
  9. 将PPT内容导出为JPG图片
  10. 资源放送丨《PostgreSQL中的锁》PPT视频
  11. java 彻底删除文件_如何删除java文件
  12. 易语言php验证码识别,易语言自动打码验证码服务端带案例
  13. java 响应式编程_响应式编程
  14. TIPTOP、T100系统程序的内置函数使用详解
  15. 算法:合唱队形(最大上升子序列,线性DP)
  16. 单层神经网络实现手写数字识别
  17. JSP 手机销售管理系统 myeclipse开发web网页 mysql数据库
  18. python-pdf的去水印操作
  19. xp sp3 远程桌面连接到控制台
  20. Linux 网络文件共享服务详细介绍

热门文章

  1. linux 下常见启动文件配置
  2. CStatic 控件设置文本,不能重回问题
  3. 搭建服务器集群——Windows7系统中nginx与IIS服务器搭建集群实现负载均衡
  4. C/C++变量在嵌套域内可见
  5. eclipse + android 自动补全
  6. 设计模式05-建造者模式
  7. 10款人气暴涨的PHP开源工具
  8. 修正STM32F103ZE的散列文件
  9. 一个用于读写配置文件的类
  10. Map.putAll()用法