洛谷P1168 中位数——set/线段树
先上一波链接 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/线段树的更多相关文章
- 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)
Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
- 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)
洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...
- 洛谷P4065 [JXOI2017]颜色(线段树)
题意 题目链接 Sol 线段树板子题都做不出来,真是越来越菜了.. 根据题目描述,一个合法区间等价于在区间内的颜色没有在区间外出现过. 所以我们可以对于每个右端点,统计最长的左端点在哪里,刚开始以为这 ...
- 洛谷P5111 zhtobu3232的线段树
题意:给定线段树,上面若干个节点坏了,求能表示出多少区间. 区间能被表示出当且仅当拆出来的log个节点都是好的. 解:每个区间在最浅的节点处计算答案. 对于每个节点维护从左边过来能有多少区间,从右边过 ...
- 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay
正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...
- 题解——洛谷P2781 传教(线段树)
可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\( n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...
- 洛谷P4198 楼房重建(线段树)
题意 题目链接 Sol 别问我为什么发两遍 就是为了骗访问量 这个题的线段树做法,,妙的很 首先一个显然的结论:位置\(i\)能被看到当且仅当\(\frac{H_k}{k} < \frac{H_ ...
- 2018.08.16 洛谷P1471 方差(线段树)
传送门 线段树基本操作. 把那个方差的式子拆开可以发现只用维护一个区间平方和和区间和就可以完成所有操作. 同样区间修改也可以简单的操作. 代码: #include<bits/stdc++.h&g ...
随机推荐
- Windows Server 搭建企业无线认证(NPS搭建)
现代企业无线网络是必备,移动办公更是需求日益剧增.而带来的无线网络安全隐患随之而来,也是面临着巨大的挑战.所以对无线网络做接入认证是现在企业很迫切的需求. 上一遍已经说明了Radius认证方案:htt ...
- 又一年NOIP后的一波总结
(昨天正式考完了吧...先写一下现在的感受,出成绩以及后续继续更...) 按照国际惯例,还是先讲一下故事吧. Day(~,0] 大概是跟随者时间的推进,气氛越来越紧张吧. 平时好像大家和往常一样,日常 ...
- HTML水平居中和垂直居中的实现方式
父元素是块元素,根据子元素不同分为以下几种: 1.子元素是行内元素: a.水平居中:在父元素上设置text-align:center; b.垂直居中:在行内子元素上设置行高与父元素相同line-hei ...
- 微信小程序request(ajax)接口请求封装
微信小程序request(ajax)接口请求封装 最近在进行小程序的编写,需要调用后端接口,经常要用到wx.request方法,所以就自己封装了一下,简化一下代码,如果能给大家提供帮助更好,在封装的时 ...
- 第四讲 自定义Realm来实现身份认证
1.jdbcReam已经实现了从数据库中获取用户的验证信息,但是jdbcRealm灵活性太差.如果要实现自己的一些特殊应用时,将不能支持.这时,可以通过自定义Realm来实现身份的认证功能. 2.Re ...
- C# 实现实体类和Xml转换
一.实体类转换成XML 将实体类转换成XML需要使用XmlSerializer类的Serialize方法,将实体类序列化 public static string XmlSerialize<T& ...
- k8s阅读笔记3-k8s的网络解析
前言 阅读地址https://rootsongjc.gitbooks.io/kubernetes-handbook/content/concepts/flannel.html k8s客户端的启动 顺序 ...
- Java垃圾回收【GC】机制详解
一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二. ...
- Promise.all 的原理
// all的原理 Promise.all = function(values){ return new Promise((resolve,reject)=>{ let results = [] ...
- B2C自营商城的订单设计方案
B2C自营商城的订单设计方案 2018年06月01日 17:19:00 lkx94 阅读数 1640 去年我们的美妆社区APP,上线了自有商城.之后经过多次版本迭代,商城系统的模块已经基本健全,值 ...