傳送門
首先考慮的是二叉搜尋樹,每次查詢當前排名(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 資...