1. 程式人生 > >洛谷 P1168 中位數

洛谷 P1168 中位數

upd 輸入格式 div show median for 所有 clas clu

題目描述

給出一個長度為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; }

洛谷 P1168 中位數