洛谷 题解 P3871 【[TJOI2010]中位数】
这题先定义一个大根堆(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]中位数】的更多相关文章
- 洛谷 P3871 [TJOI2010]中位数 解题报告
P3871 [TJOI2010]中位数 题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前 ...
- 洛谷——P3871 [TJOI2010]中位数
P3871 [TJOI2010]中位数 一眼秒掉,这不是splay水题吗,套模板 #include<bits/stdc++.h> #define IL inline #define N 1 ...
- 洛谷 题解 UVA572 【油田 Oil Deposits】
这是我在洛谷上的第一篇题解!!!!!!!! 这个其实很简单的 我是一只卡在了结束条件这里所以一直听取WA声一片,详细解释代码里见 #include<iostream> #include&l ...
- 洛谷 题解 P1600 【天天爱跑步】 (NOIP2016)
必须得说,这是一道难题(尤其对于我这样普及组205分的蒟蒻) 提交结果(NOIP2016 天天爱跑步): OJ名 编号 题目 状态 分数 总时间 内存 代码 / 答案文件 提交者 提交时间 Libre ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
- 洛谷P3871 [TJOI2010]中位数(splay)
题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前序列的中位数 中位数是指将一个序列按照从 ...
- 【题解】Luogu P3871 [TJOI2010]中位数
平衡树板题 原题传送门 这道题要用Splay,我博客里有对Splay的详细介绍 每次加入一个数,把数插入平衡树中 并且要记录一共有多少个数 每次查询就查询平衡树中第(总数-1)/2+1个数 十分暴力 ...
- 洛谷题解 CF777A 【Shell Game】
同步题解 题目翻译(可能有童鞋没读懂题面上的翻译) 给你三张牌0,1,2. 最初选一张,然后依次进行n次交换,交换规则为:中间一张和左边的一张,中间一张和右边一张,中间一张和左边一张...... 最后 ...
- 洛谷题解 CF807A 【Is it rated?】
同步题解 题目 好吧,来说说思路: 1.先读入啦~(≧▽≦)/~啦啦啦 2.判断a[i]赛前赛后是否同分数,如果分数不同,则输出,return 0 . 3.如果同分数,则判断a[i]赛前(或赛后)是否 ...
随机推荐
- 全文检索方案Elasticsearch【Python-Django 服务端开发】
更详细请看 https://www.elastic.co/cn/ 1. 全文检索和搜索引擎原理 商品搜索需求 当用户在搜索框输入商品关键字后,我们要为用户提供相关的商品搜索结果. 商品搜索实现 可以选 ...
- 挂起(suspend)与线程阻塞工具类LockSupport
挂起(suspend)与线程阻塞工具类LockSupport 一般来说是不推荐使用suspend去挂起线程的,因为suspend在导致线程暂停的同时,并不会去释放任何锁资源. 如果其他任何线程想要访问 ...
- 个人使用的lilypond第一个模板
手残非要用lilypond打谱真是…… 可是lilypond又能满足各种细节标记和谱文混排,这是musescore达不到的 所以还是开这个坑,希望能逐渐自己有能力编写自己的音乐教材 个人用Fresco ...
- 看完这篇还不清楚Netty的内存管理,那我就哭了!
说明 在学习Netty的时候,ByteBuf随处可见,但是如何高效分配ByteBuf还是很复杂的,Netty的池化内存分配这块还是比较难的,很多人学习过,看过但是还是云里雾里的,本篇文章就是主要来讲解 ...
- git submodule 子模块
### 背景:为什么要用子模块? 在开发项目中可能会遇到这种问题:在你的项目中使用另一个项目,也许这是一个第三方开发的库,或者是你独立开发的并在多个父项目中使用的.简单来说就是A同学开发了一个模块,被 ...
- SpringBoot分布式:Dubbo+zookeeper
西部开源-秦疆老师:SpringBoot + Dubbo + zookeeper 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! 基础知识 ...
- SAP-批量删除生产订单
1.SE38运行:PPARCHP1 2.先用COOIS导出订单,已经CLSD,没有删除的
- 洛谷 P1939 矩阵加速(数列)
题意简述 \(a[1]=a[2]=a[3]=1\) \(a[x]=a[x−3]+a[x−1](x>3)\) 求a数列的第n项对1000000007取余的值. 题解思路 矩阵加速 设\[ F=\b ...
- S3C2440 移植最新5.2linux内核
基于 移植uboot后. 1. 移植linux内核 1.1 下载源码 打开 https://www.kernel.org/ 直接肝最新的 5.2.8 下载完后,在ubuntu里解压备用. 1.2 搭建 ...
- 安装Windows Server 2008
下面介绍一下,Windows Server操作系统安装,以及在企业中的应用,在小型企业中可以使用不同的版本搭建不同类型的服务,小型企业中可以搭建Web服务,FTP服务,以及DNS和DHCP服务等,在大 ...