首页 > 其他分享 >[刷题笔记] Luogu P1168 中位数

[刷题笔记] Luogu P1168 中位数

时间:2023-07-18 22:22:44浏览次数:43  
标签:q1 q2 Luogu 中位数 mid 小根堆 include P1168 刷题

Problem

Description

题目描述非常简洁,不作解释。

Solution

题目要求对前奇数项求中位数?朴素的做法是暴力,但是范围1e5显然T。这里主要介绍一种堆顶堆的做法。

堆顶堆是什么呢?我们不妨开两个堆,一个大根堆一个小根堆。动态维护中位数,初始令前1位的中位数为\(a_i\),遍历数组,若遇到比中位数\(m\)小的数则放到大根堆,否则放到小根堆。

我们发现,若大根堆内的元素数=小根堆内的元素数时,\(m\)恰好为此时的中位数。若不满足呢?分类讨论一下:

  • 若大根堆内元素数 > 小根堆内元素数,则此时的中位数为大根堆堆顶,把原来的\(m\)放到小根堆。
  • 反之则中位数肯定在小根堆,把原来的\(m\)放到大根堆,小根堆堆顶为\(m\)

我们发现,每次遍历到奇数时,进行上述操作使两个堆平衡,平衡完的\(m\)显然就是此时的中位数。

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#define N 100010
using namespace std;
priority_queue <int> q1; //开大根堆和小根堆
priority_queue<int,vector<int>,greater<int> >q2;
int mid;
int n;
int a[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	mid = a[1];
	cout<<mid<<endl;
	for(int i=2;i<=n;i++)
	{
		if(a[i] > mid) q2.push(a[i]);
		else q1.push(a[i]);
		if(i%2 == 1)
		{
			while(q1.size() != q2.size()) //查询到奇数动态平衡
			{
				if(q1.size() > q2.size()) 
				{
					q2.push(mid);
					mid = q1.top();
					q1.pop();
				}
				else
				{
					q1.push(mid);
					mid = q2.top();
					q2.pop();
				}
			}
			cout<<mid<<endl;	
		}
	}
} 

标签:q1,q2,Luogu,中位数,mid,小根堆,include,P1168,刷题
From: https://www.cnblogs.com/SXqwq/p/17564287.html

相关文章

  • [刷题笔记] 异或
    Problem给定一个包含\(n\)个数的可重集,每个数为0或1,初始时答案变量\(ans=0\)。你需要进行\(n-1\)次操作,每次操作进行如下:选取可重集中的两个数\(x,y\),并计算出\(z=x\operatorname{xor}y\)。将\(ans\)增加\(z\)。在可重集中删除\(x,y\),并加入\(z\)......
  • 数据结构刷题
    山理工数据结构刷题专题1--顺序表专题2--栈和队列专题3--串和数组专题4--二叉树专题5--二叉查找树和平衡二叉树树结构练习——排序二叉树的中序遍历#include<bits/stdc++.h>#defineyescout<<"YES"<<'\n'#defineno cout<<"NO"<<'\n'usingnamespace......
  • 洛谷 Luogu P1038 [NOIP2003 提高组] 神经网络
    这题看着很吓人实则很简单。求输出层,正着求很麻烦,因为知不道谁连向这个点,所以可以反向建边,反着求。拓扑+dfs,时间复杂度\(\text{O(n+m)}\)#include<iostream>#include<cstdio>#include<queue>#defineN105#defineM(N*N/2+114)structE{intv,w;......
  • leetcode刷题记录Java
    难度等级:简单给你两个字符串word1和word2。请你从word1开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。返回合并后的字符串。classSolution{publicStringmergeAlternately(Stringword1,St......
  • leetcode刷题记录(C语言)
    给你两个字符串word1和word2。请你从word1开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。返回合并后的字符串。输入:word1="abc",word2="pqr"输出:"apbqcr"解释:字符串合并情况如下所示:word1:a......
  • luogu-modle
    P3383【模板】线性筛素数https://blog.csdn.net/huang_miao_xin/article/details/51331710首先看一个关于质数分布的规律:大于等于5的质数一定和6的倍数相邻。例如5和7,11和13,17和19等等;在6的倍数相邻两侧并不是一定就是质数。证明:令x≥1,将大于等于5的自然数可表示成:[6x-1......
  • luogu0_entry
    新手场和普及场前6关新手场顺序与分支P1422小玉家的电费控制输出精度:cout.xxx();待查询P1089津津的储蓄计划注意int和float相乘,输出格式用"%d"数字会面目全非P1909买铅笔INT_MAX存在<limits.h>里,不加.h也不行循环P1035级数求和我写了一个求和的函数Sn(in......
  • luogu1_dfsbfs
    普及练习场知识点汇总:DFS、BFS、☆杨辉三角P1118USACO06FEB数字三角形☆求解的个数用深搜,求最优解用广搜。DFSP1219八皇后弱智一样的我,还建立NxN的矩阵来模拟。结果呢,检查(check)时要遍历整个棋盘,最终导致只能过部分。根本不用二维矩阵。dfs(i),因为传进来的i是行号,......
  • luogu2_fenzhi_math
    知识点:快速幂高精负进制分治P1226【模板】快速幂||取余运算https://www.luogu.org/blog/costudy/base-2就看这一篇题解!!!然后下面备份一下代码:intquickPow(inta,intb){ intans=1;while(b){if(b&1)//b是奇数吗?(最后一位是1) ans*=a; a*=a;b>>=1......
  • luogu4_dp
    背包问题、线性动归、多维动归、技巧与记忆化《背包问题九讲》背包九讲01\完全\多重\混合01(每个物品仅1个总容量V不用装满)fori=1..n forj=V..v[i] ans[j]=max(ans[j],ans[j-v[i]]+w[i]);完全(商品可多次取)fori=1..n forj=v[i]..V//区别在此 ans[......