D - Median of Medians

Time limit : 2sec / Memory limit : 1024MB

Score : 700 points
Problem Statement

We will define the median of a sequence b of length M, as follows:

    Let b' be the sequence obtained by sorting b in non-decreasing order. Then, the value of the (M⁄2+1)-th element of b' is the median of b. Here, ⁄ is integer division, rounding down.

For example, the median of (10,30,20) is 20; the median of (10,30,20,40) is 30; the median of (10,10,10,20,30) is 10.

Snuke comes up with the following problem.

You are given a sequence a of length N. For each pair (l,r) (1≤l≤r≤N), let ml,r be the median of the contiguous subsequence (al,al+1,…,ar) of a. We will list ml,r for all pairs (l,r) to create a new sequence m. Find the median of m.
Constraints

    1≤N≤105
    ai is an integer.
    1≤ai≤109

Input

Input is given from Standard Input in the following format:

N
a1 a2 … aN

Output

Print the median of m.
Sample Input 1
Copy

3
10 30 20

Sample Output 1
Copy

30

The median of each contiguous subsequence of a is as follows:

    The median of (10) is 10.
    The median of (30) is 30.
    The median of (20) is 20.
    The median of (10,30) is 30.
    The median of (30,20) is 30.
    The median of (10,30,20) is 20.

Thus, m=(10,30,20,30,30,20) and the median of m is 30.
Sample Input 2
Copy

1
10

Sample Output 2
Copy

10

Sample Input 3
Copy

10
5 9 5 9 8 9 3 5 4 3

Sample Output 3
Copy

8

题意:给出一个序列,求每个子区间中中位数的中位数

题解:

首先如果A过牛客第一场提高组集训T1的神仙们肯定会知道前缀和+二分搞所有区间中位数的玩法

大致操作如下:

如果一个数比mid大,把它赋值为-1否则为1

对这个数组来个前缀和

此时如果某个区间的和为正数说明这个区间的中位数比mid小

然后问题转化成如何求现在有多少个这个区间

显然对前缀和求个顺序对就可以啦

接着就是二分答案

复杂度nlognlogai

代码如下:

  1. #include<bits/stdc++.h>
  2. #define lson root<<1
  3. #define rson root<<1|1
  4. using namespace std;
  5. int n;
  6. int a[];
  7. int sum[];
  8. struct node
  9. {
  10. int l,r,sum;
  11. }tr[];
  12. int push_up(int root)
  13. {
  14. tr[root].sum=tr[lson].sum+tr[rson].sum;
  15. }
  16. int build(int root,int l,int r)
  17. {
  18. if(l==r)
  19. {
  20. tr[root].sum=;
  21. tr[root].l=l;
  22. tr[root].r=r;
  23. return ;
  24. }
  25. tr[root].l=l;
  26. tr[root].r=r;
  27. int mid=(l+r)>>;
  28. build(lson,l,mid);
  29. build(rson,mid+,r);
  30. push_up(root);
  31. }
  32. int update(int root,int pos)
  33. {
  34. if(pos==tr[root].l&&pos==tr[root].r)
  35. {
  36. tr[root].sum++;
  37. return ;
  38. }
  39. int mid=(tr[root].l+tr[root].r)>>;
  40. if(pos<=mid)
  41. {
  42. update(lson,pos);
  43. }
  44. else
  45. {
  46. update(rson,pos);
  47. }
  48. push_up(root);
  49. }
  50. int query(int root,int l,int r)
  51. {
  52. if(l>r) return ;
  53. if(l<=tr[root].l&&tr[root].r<=r) return tr[root].sum;
  54. int mid=(tr[root].l+tr[root].r)>>;
  55. if(r<=mid)
  56. {
  57. return query(lson,l,r);
  58. }
  59. else
  60. {
  61. if(l>mid)
  62. {
  63. return query(rson,l,r);
  64. }
  65. else
  66. {
  67. return query(lson,l,mid)+query(rson,mid+,r);
  68. }
  69. }
  70. }
  71. int check(int x)
  72. {
  73. long long ans=;
  74. memset(sum,,sizeof(sum));
  75. for(int i=;i<=n;i++)
  76. {
  77. sum[i]=sum[i-]+((a[i]<=x)?:-);
  78. }
  79. for(int i=;i<=n;i++)
  80. {
  81. sum[i]+=n+;
  82. }
  83. build(,,);
  84. for(int i=;i<=n;i++)
  85. {
  86. ans+=query(,,sum[i]-);
  87. update(,sum[i]);
  88. }
  89. return ans>=1ll*n*(n+)/+;
  90. }
  91. int main()
  92. {
  93. scanf("%d",&n);
  94. for(int i=;i<=n;i++)
  95. {
  96. scanf("%d",&a[i]);
  97. }
  98. int l=,r=1e9,mid;
  99. while(l<=r)
  100. {
  101. mid=(l+r)>>;
  102. if(check(mid))
  103. {
  104. r=mid;
  105. }
  106. else
  107. {
  108. l=mid+;
  109. }
  110. if(r-l<=)
  111. {
  112. mid=check(l)?l:r;
  113. break;
  114. }
  115. }
  116. printf("%d\n",mid);
  117. }

AtCoder - 4351 Median of Medians(二分+线段树求顺序对)的更多相关文章

  1. AtCoder Regular Contest 101 (ARC101) D - Median of Medians 二分答案 树状数组

    原文链接https://www.cnblogs.com/zhouzhendong/p/ARC101D.html 题目传送门 - ARC101D 题意 给定一个序列 A . 定义一个序列 A 的中位数为 ...

  2. HDU4614 Vases and Flowers 二分+线段树

    分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...

  3. J - Joseph and Tests Gym - 102020J (二分+线段树)

    题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...

  4. Educational Codeforces Round 61 D 二分 + 线段树

    https://codeforces.com/contest/1132/problem/D 二分 + 线段树(弃用结构体型线段树) 题意 有n台电脑,只有一个充电器,每台电脑一开始有a[i]电量,每秒 ...

  5. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  6. hdu6070 Dirt Ratio 二分+线段树

    /** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...

  7. K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)

    大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...

  8. 2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)

    原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthes ...

  9. UVA 11983 Weird Advertisement --线段树求矩形问题

    题意:给出n个矩形,求矩形中被覆盖K次以上的面积的和. 解法:整体与求矩形面积并差不多,不过在更新pushup改变len的时候,要有一层循环,来更新tree[rt].len[i],其中tree[rt] ...

随机推荐

  1. Android图形动画

    一.动画基础 本质 每帧绘制不同的内容. 基本过程 开始动画后,调用View的invalidate触发重绘.重绘后检查动画是否停止,若未停止则继续调用invalidate触发下一帧(下一次重绘),直到 ...

  2. Numpy随机数

    Numpy随机数 np.random随机数子库 1: 基本函数 .rand(d0,d1,..dn):创建d0-dn维度的随机数数组,浮点数,范围从0-1,均匀分布 .randn(d0,d1,..dn) ...

  3. 发布Maven项目 nexus

    1.在pom.xml文件中配置需要发布的工厂 如果想把项目发布到nexus中,需要在pom.xml中配置releases和snapshots版本发布的具体repository <distribu ...

  4. android笔记:ListView及ArrayAdapter

    ListView用于展示大量数据,而数据无法直接传递给ListView,需要借助适配器adapter来完成. ArrayAdapter是最常用的adapter,可以通过泛型来指定要适配的数据类型.常见 ...

  5. 37. Sudoku Solver (Array;Back-Track)

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  6. ES5之defineProperty

    一 概述 Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 对象里目前存在的属性描述符有两种主要形式:数据描述符和存 ...

  7. OC线程操作-GCD介绍

    1. GCD介绍 1.11.2 1.3 异步具备开启能力但是不是 一定可以开启 1.4 1.5 67. 8.

  8. php Pthread 多线程 (六) Pool类 线程池

    Pool对象是多个Worker对象的容器,同时也是它们的控制器,对Worker功能更高抽象. 比如Worker是河,而线程是运行在河里的船.Pool则是管理着多条河. <?php //继承Col ...

  9. Spring框架的IOC核心功能快速入门

    2. 步骤一:下载Spring框架的开发包 * 官网:http://spring.io/ * 下载地址:http://repo.springsource.org/libs-release-local/ ...

  10. 在windows系统下安装oracle 11g

     oracle 11g 安装在windows server 2012 系统下. 最近,需要配置数据库,要求在windows操作系统下,安装oracle 11g 数据库,因为以前没有安装过,所以成功后, ...