这题先定义一个大根堆(maxn)维护mid(n为奇数mid+1)的元素。再定义一个小根堆(minn)维护mid(n为奇数mid+1)到n的元素。然后对于插入元素的情况进行分类讨论。

当add x时

一.n 是奇数

1.从大根堆中取出元素y并弹出。

2.大根堆中插入元素min(x,y)。

3.小根堆中插入元素max(x,y)。

二.n 是偶数

1.从小根堆中取出元素y并弹出。

2.大根堆中插入元素min(x,y)。

3.小根堆中插入元素max(x,y)。

当询问时输出大根堆中的堆顶元素即可。

addmax(大根堆中元素个数) addmin(小根堆中元素个数) maxn(大根堆) minn(小根堆)

堆的操作(以大根堆为例)

1.堆的元素下调

void shiftdownmax(int x){
int t,flag=0;
while(x*2<=addmax&&flag==0){
if(maxn[x]<maxn[x*2])t=x*2;
else t=x;
if(x*2+1<=addmax){
if(maxn[t]<maxn[x*2+1])t=x*2+1;
}
if(t!=x){
swap(maxn[t],maxn[x]);
x=t;
}else flag=1;
}
}

2.堆的元素上调

void shiftdownmax(int x){
int t,flag=0;
while(x*2<=addmax&&flag==0){
if(maxn[x]<maxn[x*2])t=x*2;
else t=x;
if(x*2+1<=addmax){
if(maxn[t]<maxn[x*2+1])t=x*2+1;
}
if(t!=x){
swap(maxn[t],maxn[x]);
x=t;
}else flag=1;
}
}

3.建堆

由于堆的性质,只要调整一半的元素即可。

for(int i=1;i<=tmp;++i){
addmax++;
maxn[addmax]=a[i];
}
for(int i=addmax/2;i>=1;--i){
shiftdownmax(i);
}

4.取出元素

取出第一个元素将最后一个元素放在第一个元素的位置,并且元素个数减1,对堆顶进行下调操作。

int y=maxn[1];
maxn[1]=maxn[addmax--];
shiftdownmax(1);

5.加入元素

在堆尾加入新元素并且对其进行上调操作

maxn[++addmax]=min(x,y);
shiftupmax(addmax);

ac代码

#include<bits/stdc++.h>
using namespace std;
int n,m,x,addmax,addmin,a[100010],maxn[60010],minn[60010];
char str[5];
void shiftdownmax(int x){//大根堆向下调整
int t,flag=0;
while(x*2<=addmax&&flag==0){
if(maxn[x]<maxn[x*2])t=x*2;
else t=x;
if(x*2+1<=addmax){
if(maxn[t]<maxn[x*2+1])t=x*2+1;
}
if(t!=x){
swap(maxn[t],maxn[x]);
x=t;
}else flag=1;
}
}
void shiftdownmin(int x){//小根堆向下调整
int t,flag=0;
while(x*2<=addmin&&flag==0){
if(minn[x]>minn[x*2])t=x*2;
else t=x;
if(x*2+1<=addmin){
if(minn[t]>minn[x*2+1])t=x*2+1;
}
if(t!=x){
swap(minn[t],minn[x]);
x=t;
}else flag=1;
}
}
void shiftupmax(int x) {//大根堆向上调整
int flag=0;
if(x==1) return;
while(x!=1&&flag==0){
if(maxn[x]>maxn[x/2]) swap(maxn[x],maxn[x/2]);
else flag=1;
x=x/2;
}
}
void shiftupmin(int x) {//小根堆向上调整
int flag=0;
if(x==1) return;
while(x!=1 && flag==0){
if(minn[x]<minn[x/2]) swap(minn[x],minn[x/2]);
else flag=1;
x=x/2;
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
addmax=0;
addmin=0;
sort(a+1,a+1+n);
if(n==1) maxn[++addmax]=a[1];//考虑特殊情况
else{
int tmp=n/2;
if(n%2) tmp++;
for(int i=1;i<=tmp;++i){
addmax++;
maxn[addmax]=a[i];
}
for(int i=addmax/2;i>=1;--i){
shiftdownmax(i);
}
for(int i=tmp+1;i<=n;++i){
addmin++;
minn[addmin]=a[i];
}
for(int i=addmin/2;i>=1;--i){
shiftdownmin(i);
}
}
scanf("%d",&m);
while(m--){
scanf("%s",str);
if(str[0]=='m'){
printf("%d\n",maxn[1]);
}
else{
scanf("%d",&x);
if(n%2){
int y=maxn[1];
maxn[1]=maxn[addmax--];
shiftdownmax(1);
maxn[++addmax]=min(x,y);
shiftupmax(addmax);
minn[++addmin]=max(x,y);
shiftupmin(addmin);
n++;//记得更新n
}
else{
int y=minn[1];
minn[1]=minn[addmin--];
shiftdownmin(1);
minn[++addmin]=max(x,y);
shiftupmin(addmin);
maxn[++addmax]=min(x,y);
shiftupmax(addmax);
n++;
}
}
}
return 0;
}

洛谷 题解 P3871 【[TJOI2010]中位数】的更多相关文章

  1. 洛谷 P3871 [TJOI2010]中位数 解题报告

    P3871 [TJOI2010]中位数 题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前 ...

  2. 洛谷——P3871 [TJOI2010]中位数

    P3871 [TJOI2010]中位数 一眼秒掉,这不是splay水题吗,套模板 #include<bits/stdc++.h> #define IL inline #define N 1 ...

  3. 洛谷 题解 UVA572 【油田 Oil Deposits】

    这是我在洛谷上的第一篇题解!!!!!!!! 这个其实很简单的 我是一只卡在了结束条件这里所以一直听取WA声一片,详细解释代码里见 #include<iostream> #include&l ...

  4. 洛谷 题解 P1600 【天天爱跑步】 (NOIP2016)

    必须得说,这是一道难题(尤其对于我这样普及组205分的蒟蒻) 提交结果(NOIP2016 天天爱跑步): OJ名 编号 题目 状态 分数 总时间 内存 代码 / 答案文件 提交者 提交时间 Libre ...

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

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

  6. 洛谷P3871 [TJOI2010]中位数(splay)

    题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前序列的中位数 中位数是指将一个序列按照从 ...

  7. 【题解】Luogu P3871 [TJOI2010]中位数

    平衡树板题 原题传送门 这道题要用Splay,我博客里有对Splay的详细介绍 每次加入一个数,把数插入平衡树中 并且要记录一共有多少个数 每次查询就查询平衡树中第(总数-1)/2+1个数 十分暴力 ...

  8. 洛谷题解 CF777A 【Shell Game】

    同步题解 题目翻译(可能有童鞋没读懂题面上的翻译) 给你三张牌0,1,2. 最初选一张,然后依次进行n次交换,交换规则为:中间一张和左边的一张,中间一张和右边一张,中间一张和左边一张...... 最后 ...

  9. 洛谷题解 CF807A 【Is it rated?】

    同步题解 题目 好吧,来说说思路: 1.先读入啦~(≧▽≦)/~啦啦啦 2.判断a[i]赛前赛后是否同分数,如果分数不同,则输出,return 0 . 3.如果同分数,则判断a[i]赛前(或赛后)是否 ...

随机推荐

  1. redis缓存介绍以及常见问题浅析

    # 没缓存的日子: 对于web来说,是用户量和访问量支持项目技术的更迭和前进.随着服务用户提升.可能会出现一下的一些状况: 页面并发量和访问量并不多,mysql足以支撑自己逻辑业务的发展.那么其实可以 ...

  2. 数据结构之堆栈C++版

    /* 堆栈本身就是一种线性数据结构,说白了他与容器线性表是一种数据类型,不要认为他多高大上. 实时上他还没有线性表复杂,下面简单的实现一下堆栈. 事实上整个核心操作都是在操作指向堆栈的顶部元素的指针 ...

  3. [译]使用golang每分钟处理百万请求

    [译]使用golang每分钟处理百万请求 在Malwarebytes,我们正在经历惊人的增长,自从我在1年前加入硅谷的这家公司以来,我的主要职责是为多个系统做架构和开发,为这家安全公司的快速发展以及百 ...

  4. django drf框架中的user验证以及JWT拓展的介绍

    登录注册是几乎所有网站都需要去做的接口,而说到登录,自然也就涉及到验证以及用户登录状态保存,最近用DRF在做的一个关于网上商城的项目中,引入了一个拓展DRF JWT,专门用于做验证和用户状态保存.这个 ...

  5. Linux常用命令之压缩解压

    压缩是一种通过特定的算法来减小计算机文件大小的机制.这种机制对网络用户是非常有用和高效的,因为它可以减小文件的字节总数,使文件能够通过互联网实现更快传输,此外还可以减少文件的磁盘占用空间.下面简介下z ...

  6. Java学习|HTTP请求头

    https://www.cnblogs.com/honghong87/articles/6941436.html 常见http请求报文头属性      Accept:告诉服务端,客户端接受什么类型的响 ...

  7. HashMap与ConcurrentHashMap在Java8的改进

    链接:http://www.cnblogs.com/huaizuo/archive/2016/04/20/5413069.html#undefined http://www.cnblogs.com/h ...

  8. 深入剖析PHP7内核源码(一)- PHP架构与生命周期

    PHP7 为什么这么快? 全新的zval 更节约的空间,栈上分配内存 zend_string 存储字符串的Hash值,数组查询的时候不需要进行Hash计算 在HashTable桶内直接存数据,减少了内 ...

  9. OSI七层网络模型与TCP/IP四层模型

    1.OSI七层结构图: 2.TCP/IP四层结构图: 3.各层对应的协议 4.OSI七层和TCP/IP四层的区别 OSI网络模型和TCP/IP网络模型对应关系: 5.交换机工作在OSI的哪一层 如果有 ...

  10. jmeter之beanshell使用

    beanshell官网:http://www.BeanShell.org/ 一.beanshell介绍 是一种完全符合Java语法规范的轻量级的脚本语言: 相当于一个小巧免费嵌入式的Java源代码解释 ...