先上一波链接 https://www.luogu.com.cn/problem/P1168

这道题我们有两种写法

第一种呢是线段树,我们首先需要将原本的数据离散化,线段树维护的信息就是区间内有多少个数,

每次加入两个数(也就是单点修改),查询的时候就是查找中位数((x+1)/2 )所在的位置

每次走到一个点 判断左子树中数字的个数(y)是不是就大于等于当前所找的数k 如果是 则往左子树继续走

如果左子树的数字个数(y)小于当前所找的数k,那么就将k减去y,再往右子树走,这样一直走下去就可以找到中位数所在的位置

然后再将其位置所对应的离散化前对应的点输出来就可以了 这样的复杂度是O(nlogn)的

贴一手代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int M=1e6+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
struct qwq{int w,id;}s[M];
int n,xs[M],xp,fr[M];
struct node{int l,r,sum;}e[M];
void build(int x,int l,int r){
e[x].l=l; e[x].r=r;
if(l==r) return ;
int mid=(l+r)>>;
build(x<<,l,mid);
build(x<<^,mid+,r);
}
void up(int x){e[x].sum=e[x<<].sum+e[x<<^].sum;}
void ins(int x,int k){
if(e[x].l==e[x].r){
e[x].sum++;
return ;
}
int mid=(e[x].l+e[x].r)>>;
if(k<=mid) ins(x<<,k);
else ins(x<<^,k);
up(x);
}
int find(int x,int S){
if(e[x].l==e[x].r) return e[x].l;
if(e[x<<].sum>=S) return find(x<<,S);
return find(x<<^,S-e[x<<].sum);
}
int cnt=;
int main(){
n=read();
for(int i=;i<=n;i++){
s[i].w=read();
xs[++xp]=s[i].w;
}
sort(xs+,xs++xp);
for(int i=;i<=n;i++){
int now=lower_bound(xs+,xs+xp+,s[i].w)-xs;
s[i].id=now; fr[now]=s[i].w;
}
// for(int i=1;i<=n;i++) printf("%d ",s[i].id); puts("");
// for(int i=1;i<=n;i++) printf("%d ",fr[i]); puts("");
build(,,n);
ins(,s[].id);
for(int i=;i<=n;i+=){
int ans=find(,(i+)/);
printf("%d\n",fr[ans]);
ins(,s[++cnt].id);
ins(,s[++cnt].id);
}
return ;
}

另一种做法就是用multiset维护,我们将迭代器It 始终指向中位数,每次插入两个数

如果两个数都比他大,就将It++,因为此时中位数在当前 It 所在位置的后一位了

同理如果两个数都比他小,就将 It--, 如果一大一小,那么中位数位置不变,这样就圆满解决了问题

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
using namespace std;
const int M=1e6+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,s[M],ans[M];
multiset<int>S;
multiset<int>::iterator It;
int main(){
//freopen("1.in","r",stdin);
n=read(); for(int i=;i<=n;i++) s[i]=read();
S.insert(s[]);
It=S.lower_bound(s[]);
int cnt=;
for(int i=;i<=(n+)/;i++){
ans[i]=*It;
S.insert(s[++cnt]);
S.insert(s[++cnt]);
if(s[cnt]>=*It&&s[cnt-]>=*It) ++It;
else if(s[cnt]<*It&&s[cnt-]<*It) --It;
printf("%d\n",ans[i]);
}
return ;
}

洛谷P1168 中位数——set/线段树的更多相关文章

  1. 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  2. 洛谷题解P4314CPU监控--线段树

    题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...

  3. 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)

    洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...

  4. 洛谷P4065 [JXOI2017]颜色(线段树)

    题意 题目链接 Sol 线段树板子题都做不出来,真是越来越菜了.. 根据题目描述,一个合法区间等价于在区间内的颜色没有在区间外出现过. 所以我们可以对于每个右端点,统计最长的左端点在哪里,刚开始以为这 ...

  5. 洛谷P5111 zhtobu3232的线段树

    题意:给定线段树,上面若干个节点坏了,求能表示出多少区间. 区间能被表示出当且仅当拆出来的log个节点都是好的. 解:每个区间在最浅的节点处计算答案. 对于每个节点维护从左边过来能有多少区间,从右边过 ...

  6. 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay

    正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...

  7. 题解——洛谷P2781 传教(线段树)

    可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\(  n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...

  8. 洛谷P4198 楼房重建(线段树)

    题意 题目链接 Sol 别问我为什么发两遍 就是为了骗访问量 这个题的线段树做法,,妙的很 首先一个显然的结论:位置\(i\)能被看到当且仅当\(\frac{H_k}{k} < \frac{H_ ...

  9. 2018.08.16 洛谷P1471 方差(线段树)

    传送门 线段树基本操作. 把那个方差的式子拆开可以发现只用维护一个区间平方和和区间和就可以完成所有操作. 同样区间修改也可以简单的操作. 代码: #include<bits/stdc++.h&g ...

随机推荐

  1. 什么是服务端伪造(SSRF)

    什么是服务端伪造(SSRF) 原文:GitHub Pages and Single-Page Apps 译者:neal1991 welcome to star my articles-translat ...

  2. 自己实现一个Redux

    Redux是一个可预测的状态容器,提供可预测的状态管理. 什么是状态?状态其实也就是数据,管理状态也就是对数据的管理.那么什么是可预测的状态管理呢?能够监听数据的变化,获取变化的来源,在发生变化时可以 ...

  3. js url传参,参数加密

    前台 function encode64(input) { var output = ""; var base = new Base64(); var output = base. ...

  4. C# 获得系统环境

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 【LeetCode】动态规划(下篇共39题)

    [600] Non-negative Integers without Consecutive Ones [629] K Inverse Pairs Array [638] Shopping Offe ...

  6. CSS3 结构性伪类选择器(1)

    1.CSS3 结构性伪类选择器—root :root选择器就是匹配元素E所在文档的根元素.在HTML文档中,根元素始终是<html>. “:root”选择器等同于<html>元 ...

  7. MySQL重复数据中限定操作n条

    对于一个表,有时可能里面有很多重复的条,比如: +-----------+---------+| coupon_id | user_id |+-----------+---------+| 8 | 1 ...

  8. AGC036C GP 2

    由于近期集训做的一直都是校内题 然后好久都怎么写题了( 发篇博客证明我还活着 (其实也没人关心 好像并不是很难的一道计数 就是脑子总是缺一块导致会做不出来( 首先我们可以分析性质 1.$\sum A_ ...

  9. SpringBoot整合MyBatis-Plus实现快速业务功能开发

    概览:使用MybatisPlus和它的代码生成整合SpringBoot可以实现快速的业务功能开发,具体步骤如下 一.添加依赖 <dependency> <groupId>org ...

  10. 对vueloader的研究

    vue-loader是webpack的加载器,允许您以称为单文件组件(SFC)的格式创作Vue组件: <template> <div class="example" ...