題解 中位數

2022-07-30 02:39:12 字數 1279 閱讀 8713

傳送門

首先考慮的是二叉搜尋樹,每次查詢當前排名(i+1)/2的數。但是對於某些資料,其遞迴層數過多,會導致爆棧。

那麼顯然可以用treap或splay。

這裡考慮線段樹:

由於線段樹是一種平衡樹,所以一定保證能跑出來。

對於線段樹,我們基於二叉搜尋樹的查詢方法並介於線段樹平衡的性質求解。

對於線段樹的每乙個節點,我們記其大小為num,並記錄其左邊最大值和右邊最小值。

在插入時我們考慮存入乙個有序數列,保證其根節點的元素單調遞增。

則其左邊最大值和右邊最小值分別為左兒子右端點和右兒子左端點。

在插入時,若:

當前值x=左最大=右最小,顯然x=根節點。

我們令根節點的num+1.

當前值x>左最大,往右放;反之,往左放。

在查詢時:

就相當於結合了二叉搜尋樹的找排名,和線段樹的單點修改的樣子。

#include#include

#include

#define lson l,mid,rn<<1

#define rson mid+1,r,rn<<1|1

using

namespace

std;

int n,a[100010],b[100010

],size;

struct

cymtree[

400010

];void update(int

rn)void build(int l,int r,int

rn)

int mid=(l+r)>>1

; build(lson);

build(rson);

update(rn);

}void add(int x,int

now)

if(x>tree[now<<1

].r_size)

add(x,now

<<1|1

);

else

add(x,now

<<1

); update(now);

}int find(int l,int r,int rn,int

rank)

intmain()

sort(b+1,b+1+n);

size=unique(b+1,b+1+n)-(b+1

); build(

1,size,1

);

for(int i=1;i<=n;i++)

}

中位數題解 c (詳細)

題目是這樣的 題目描述 給你n個整數ai和乙個整數s,題目資料保證n是奇數。1次操作可以使n個數中的任意乙個數增加1或者減少1。你現在的任務是計算出使這n個整數的中位數變為s的最小運算元是多少?輸入格式 輸入一共有兩行。第一行有兩個整數n和s,分別表示整數的個數和題目描述的s的值 第二行包含n個用空...

中位數的中位數

參照王曉東的演算法設計 中位數的中位數,即將一串數分成n段,求其排好序了的中間那個數,再把這些所有中位數再求一次中位數。for int i 0 i r p 4 5 i 找中位數的中位數,r p 4即上面所說的n 5 int x lineselect a,p,p r p 4 5,r p 4 10 線性...

中位數題解 luogu P1627

給出1 n的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是b。中位數是指把所有元素從小到大排列後,位於中間的數。輸入格式 第一行為兩個正整數n和b,第二行為1 n的排列。輸出格式 輸出乙個整數,即中位數為b的連續子串行個數。輸入樣例1 7 4 5 7 2 4 3 1 6 輸出樣例1 資...