洛谷 P1168 中位数

题目描述

给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], …, A[2k - 1]的中位数。即前1,3,5,……个数的中位数。

输入输出格式

输入格式:

输入文件median.in的第1行为一个正整数N,表示了序列长度。

第2行包含N个非负整数A[i] (A[i] ≤ 10^9)。

输出格式:

输出文件median.out包含(N + 1) / 2行,第i行为A[1], A[3], …, A[2i – 1]的中位数。

输入输出样例

输入样例#1:

7
1 3 5 7 9 11 6

输出样例#1:

1
3
5
6

说明

对于20%的数据,N ≤ 100;

对于40%的数据,N ≤ 3000;

对于100%的数据,N ≤ 100000。

主席树

题目链接

#include <algorithm>
#include <cstdio>
#define N 100005
using namespace std;
int n,tot,Size,a[N],b[N],rt[N],ls[N*30],rs[N*30],sum[N*30];
int build(int l,int r)
{
    int now=++tot;
    sum[now]=0;
    if(l==r) return now;
    int mid=(l+r)>>1;
    ls[now]=build(l,mid);
    rs[now]=build(mid+1,r);
    return now;
}
int rank(int x) {return lower_bound(b+1,b+1+Size,x)-b;}
void update(int l,int r,int x,int &y,int t)
{
    y=++tot;
    sum[y]=sum[x]+1;
    if(l==r) return;
    ls[y]=ls[x];
    rs[y]=rs[x];
    int mid=(l+r)>>1;
    if(t<=mid) update(l,mid,ls[x],ls[y],t);
    else update(mid+1,r,rs[x],rs[y],t);
}
int ask(int l,int r,int x,int y,int k)
{
    if(l==r) return l;
    int mid=(l+r)>>1;
    if(sum[ls[y]]-sum[ls[x]]>=k) return ask(l,mid,ls[x],ls[y],k);
    else {k-=sum[ls[y]]-sum[ls[x]];return ask(mid+1,r,rs[x],rs[y],k);}
}
int main(int argc,char *argv[])
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i];
    sort(b+1,b+1+n);
    Size=unique(b+1,b+1+n)-b-1;
    rt[0]=build(1,Size);
    for(int i=1;i<=n;++i) update(1,Size,rt[i-1],rt[i],rank(a[i]));
    for(int i=1;i<=n;i+=2) printf("%d\n",b[ask(1,Size,rt[0],rt[i],i/2+1)]);
    return 0;
}
时间: 2024-10-10 09:40:18

洛谷 P1168 中位数的相关文章

洛谷P1168 中位数 堆

洛谷P1168 中位数   堆 求a[ 1 ] --a[ 1 ] 的中位数 ,a[ 1 ]--a[ 3 ] 的中位数 a[ 1 ]--a[ 5 ] 的中位数 题解1.假设我们已知 a[ 1 ]--a[ i ] 的中位数 (i&1) 此时我们求 a[ 1 ]--a[ i+2 ] 的中位数 那么我们可以把比他大的划到一份中,比他小的划到一份中,如果两份数的个数相同,则其仍然是中位数2.如果不同,比如说 big > small 那我们就把比他大的数 作为中位数 ans 到比中位数小的数中因为原本s

洛谷—— P1168 中位数

https://www.luogu.org/problem/show?pid=1168 题目描述 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], …, A[2k - 1]的中位数.[color=red]即[/color]前1,3,5,……个数的中位数. 输入输出格式 输入格式: 输入文件median.in的第1行为一个正整数N,表示了序列长度. 第2行包含N个非负整数A[i] (A[i] ≤ 10^9). 输出格式: 输出文件m

[洛谷P1168]中位数

题目大意:给你n个数,问你前1.3.5...个数的中位数是多少. 解题思路:首先,前一个数的中位数一定是第一个数. 之后,每次都会读进两个数. 我们需要做到,如果两个数都小于原来的中位数,那么现在的中位数变成比它小的最大的数. 反之,如果两个数都大于等于原来的中位数,则变成比它大的最小的数. 如果一个小,一个大于等于,则显然中位数不变. 可以想到用一个大根堆保存“比当前中位数小的数”,用一个小根堆保存“大于等于当前中位数的数”, 然后,对于读进来的两个数,把比当前中位数小的放进大根堆里,大于等于

【洛谷P1168】中位数(Splay)/(主席树)

Description 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[2], -, A[2k - 1]的中位数.即前1,3,5,--个数的中位数. N ≤ 100000 Solution 这题方法很多,这里介绍splay的打法 求中位数即求第$(k+1)/$2小的数,用splay维护即可,只有2中操作:插入,旋转 在树上记录一个\(c(u)\)表示节点\(u\)的子树有几个节点,用来判断第n小 只要在插入和旋转的时候维护就行了 Cod

洛谷P1257 平面上的最接近点对 数学 分治 排序

来自洛谷上的题解 方法一: 先求第1个点与其余n-1个点的距离: 再求第2个点与其余n-2个点的距离: 再求第3个点与其余n-3个点的距离: ---------------- 再求第n-1个点与其余1个点的距离: 然后找出最小值. 如此的算法复杂度为O(n^2),显然不能满足本题的需要.但--貌似洛谷神机可以--过-- 欢迎朴素的同学挑战数据加强版新 方法二: 考虑以下分治算法: 设平面上的点都在点集S中,为了将S线性分割为大小大致相等的2个子集S1和S2,我们选取一垂直线l(方程:x=m)来作

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可

洛谷教主花园dp

洛谷-教主的花园-动态规划 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值. 教主最喜欢3种树,这3种树的高度分别为10,20,30.教主希望这一圈树种得有层次感,所以任何一个位置的树要比它相邻的两棵树的高度都高或者都低,并且在此条件下,教主想要你设计出一套方案,使得观赏价值之和最高. 输入输出格式 输入格式: 输入文件garden.in的第1行为一个正整数n,表示需要种的

洛谷 P2801 教主的魔法 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=2801 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的身高一开始都是不超过1000的正整数.教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W.(虽然L=R时并不