AtCoder Regular Contest 101 (ARC101) D - Median of Medians 二分答案 树状数组
原文链接https://www.cnblogs.com/zhouzhendong/p/ARC101D.html
题目传送门 - ARC101D
题意
给定一个序列 A 。
定义一个序列 A 的中位数为:给 A 排序,得到的第 $\left\lfloor\cfrac{i}{2}\right\rfloor+1$ 项的值。
序列 B 由序列 A 的所有连续子序列的中位数构成。
问序列 B 的中位数是多少。
序列中可能出现重复的数,$|A| \leq 10^5$ 。
题解
注意这里说的“中位数”是题意里面定义的“中位数”。
首先考虑二分答案。
对于一个数 $k$ ,我们考虑判断最终序列的中位数是否 大于等于 $k$。
考虑将原序列中 大于等于 $k$ 的数全部设置为 $1$,小于 $k$ 的数设为 $-1$ 。那么,如果一个序列的和 非负,它原来的中位数就必然大于等于 $k$ 。
考虑用树状数组统计出中位数大于等于 $k$ 的序列个数 $ans$ 。
如果 $ans\geq \cfrac{n(n+1)}4$ ,那么显然,序列 B 的中位数大于等于 $k$ 。
于是就可以在 $O(n\log^2 n)$ 的时间复杂度内解决这个问题了。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200005;
int n,a[N],Ha[N],hs,k,f[N];
struct BIT{
int n,c[N];
void set(LL _n){
n=_n;
memset(c,0,sizeof c);
}
void add(int x,int d){
for (;x<=n;x+=x&-x)
c[x]+=d;
}
int ask(int x){
int ans=0;
for (;x;x-=x&-x)
ans+=c[x];
return ans;
}
}T;
bool check(int k){
for (int i=1;i<=n;i++)
f[i]=f[i-1]+(a[i]>=k?1:-1);
T.set(n*2+1);
LL ans=0;
for (int i=0;i<=n;i++){
ans+=T.ask(f[i]+n+1);
T.add(f[i]+n+1,1);
}
return ans>=1LL*n*(n+1)/4;
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]),Ha[i]=a[i];
sort(Ha+1,Ha+n+1);
hs=unique(Ha+1,Ha+n+1)-Ha-1;
for (int i=1;i<=n;i++)
a[i]=lower_bound(Ha+1,Ha+hs+1,a[i])-Ha;
int L=1,R=hs,mid,ans=L;
while (L<=R){
mid=(L+R)>>1;
if (check(mid))
L=mid+1,ans=mid;
else
R=mid-1;
}
printf("%d",Ha[ans]);
return 0;
}
AtCoder Regular Contest 101 (ARC101) D - Median of Medians 二分答案 树状数组的更多相关文章
- AtCoder - 4351 Median of Medians(二分+线段树求顺序对)
D - Median of Medians Time limit : 2sec / Memory limit : 1024MB Score : 700 pointsProblem Statement ...
- AtCoder Regular Contest 101 D - Median of Medians
二分答案 然后前缀和+树状数组来判断这个答案是否大于等于数 如果我们对于一个查询,如果小于这个数令为1,大于这个数领为-1 将所有前缀和放在树状数组中,就可以查询所有sum_{l} < sum_ ...
- AtCoder Regular Contest 101
C题是个傻逼题, 一定是先向右,然后停了或者向左走到某一个点(左边同理)模拟就可以了 D题想了一会才想出来 和tjoi那道排序挺像的 二分答案变0/1来做 刚开始写的时候还把自己作为另外一类搞出来 这 ...
- 【AtCoder Grand Contest 007E】Shik and Travel [Dfs][二分答案]
Shik and Travel Time Limit: 50 Sec Memory Limit: 512 MB Description 给定一棵n个点的树,保证一个点出度为2/0. 遍历一遍,要求每 ...
- AtCoder Regular Contest 097
AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
随机推荐
- mysql 命令行常用命令
1.显示数据库列表. show databases; 2.显示库中的数据表: use mysql; show tables; 3.显示数据表的结构: describe 表名; 4.建库: cr ...
- LabVIEW--为控件添加说明信息
之前只知道为VI添加说明信息(在VI的属性里面添加,快捷键ctrl+I 打开),今天知道了控件也可以添加说明信息,这样就方便了许多,极大的提高了程序的可读性.
- js -- sort() 使用排序函数
JavaScript sort() 方法 JavaScript Array 对象 定义和用法 sort() 方法用于对数组的元素进行排序. 语法 arrayObject.sort(sortby) 参数 ...
- js 数组不重复添加元素
1 前言 由于使用JS的push会导致元素重复,而ES5之前没有set(集合)方法,重复元素还要做去重处理,比较麻烦些,所以直接写一个新push来处理 2 代码 Array.prototype.pus ...
- jQuery页面滚动底部加载数据
$(window).scroll(function () { var scrollTop = $(this).scrollTop(); var scrollHeight = ...
- Confluence 6 配置数字格式
在 Confluence 中使用了 2 种数字格式: 整形数字格式.例如: ############### 小数数字格式.例如:###############.########## Confluenc ...
- Confluence 6 连接到外部用户目录服务器的问题分析
在有关外部目录服务器配置页面中有一个测试配置(Test Settings)按钮.这个功能将会帮助你分析你的用户管理在 Active Directory 和其他 LDAP 服务器中出现的问题. 希望对你 ...
- javaScript遍历对象、数组总结
javaScript遍历对象总结 1.使用Object.keys()遍历 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性). var obj = {'0':'a ...
- 分布式Dubbo快速入门
目录 Dubbo入门 背景 zookeeper安装 发布Dubbo服务 Dubbo Admin管理 消费Dubbo服务 抽取与依赖版本管理 Dubbo入门 Editor:SimpleWu Dubbo是 ...
- this作用范围
1. this的指向 var name='window';var obj={ name:'obj', say:function(){ return function(){ return this.na ...