bzoj 1303 中位數 題解

2021-07-24 12:39:39 字數 2690 閱讀 1012

4.中位數

(median.pas/c/cpp)

【問題描述】

給出1~n的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是b。中位數是指把所有元素從小到大排列後,位於中間的數。

【輸入】

第一行為兩個正整數n和b ,第二行為1~n 的排列。

【輸出】

輸出乙個整數,即中位數為b的連續子串行個數。

【樣例輸入】

7 45 7 2 4 3 1 6

【樣例輸出】 4

【樣例解釋】

分別是子串行,,,

【資料範圍】

n<=100000

其實還是蠻好上手的一道題,顯然我們符合要求的序列:

1、一定包含我們的中位數,

2、而且序列內大於中位數的個數等於小於中位數的個數相等(中位數定義可知=。=)

3、序列長度為奇數

我們設中位數在序列中的位置為t

對於1~t-1

a[i],a[i+1],a[i+2]......,a[t-1]

我們用l_min[i]記錄a[i]~a[t] 中比中位數小的個數,用l_max[i]記錄a[i]~a[t]中比中位數大的個數

同理,對於a[t+1],a[t+2],...,a[n]

我們用r_min[j]記錄a[t]~a[n]中比中位數小的個數,用r_max[j]記錄a[t]~a[n]中比中位數大的個數

那麼滿足條件的序列a[i]~a[j]一定有

1.i<=t<=j

2.j-i>=2

3.l_min[i]+r_min[j]=l_max[i]+r_max[j] (i

l_min[i]=l_max[j](i

r_min[i]=r_max[j](t=i

然後分水嶺來了=w=

方法一:處理完後列舉1~t-1,t+1~n,滿足上述三條要求的加答案,期望得分70

ac方法:由於兩邊同時處理會tle,所以我們考慮一邊的min和max一起處理

於是l_min[i]+r_min[j]=l_max[i]+r_max[j]  變形(看好了我要變了!!) l_min[i]-l_max[i]=r_max[j]-r_min[j] 

即  l_min[i]-l_max[i]=-(r_min[j]-r_max[j] )

那麼我們只需要處理出 l_min[i]-l_max[i]=k的序列個數fl[k]和 r_min[j]-r_max[j]=k的序列個數fr[k]

然後ans:=σfl[k]*fr[-k] (-n<=k<=n),最壞時間複雜度o(n),完美=w=

ps:考試的時候由於我是從中位數的位置向兩邊同時去更新,導致一邊更新完成時另一邊還沒有完成更新,聽取wa聲一片qaq

在更新數值的時候,如果是從中間向兩端同時更新,在更新後要判斷兩邊是否全部完成更新,不要留下有一邊只更新一部分的情況

注意對不存在中位數m的特判

**

var

n,m,t,ans :longint;

a,lmin,lmax,rmin,rmax:array[0..100010] of longint;

t1,t2 :array[-100005..100005] of longint;

i,j :longint;

begin

read(n,m);

for i:=1 to n do read(a[i]);

for i:=1 to n do if a[i]=m then break;

t:=i;

lmin[t]:=0;lmax[t]:=0;rmin[t]:=0;rmax[t]:=0;

//for i:=t-1 downto 1 do

begin

lmin[i]:=lmin[i+1];

lmax[i]:=lmax[i+1];

if a[i]m then inc(rmax[i]) else inc(rmin[i]);

if rmax[i]=rmin[i] then inc(ans);

end;

//for i:=1 to t-1 do inc(t1[lmin[i]-lmax[i]]);

for i:=t+1 to n do inc(t2[rmin[i]-rmax[i]]);

for i:=-n to n do inc(ans,t1[i]*t2[-i]);

if t=0 then writeln(0) else writeln(ans+1);

end.

有一列數x1,x2,x3,...,xn,

f(x)=|x1-x|+|x2-x|+|x3-x|+...+|xn-x|,

當x=數列中位數時,f(x)最小

題解 中位數

傳送門 首先考慮的是二叉搜尋樹,每次查詢當前排名 i 1 2的數。但是對於某些資料,其遞迴層數過多,會導致爆棧。那麼顯然可以用treap或splay。這裡考慮線段樹 由於線段樹是一種平衡樹,所以一定保證能跑出來。對於線段樹,我們基於二叉搜尋樹的查詢方法並介於線段樹平衡的性質求解。對於線段樹的每乙個節...

P1168 中位數 題解

csdn同步 原題鏈結 簡要題意 給定乙個長度為 n 的序列 a 求 a 1 a x 的中位數。1 leq x leq n 且 x 為奇數 附註 中位數的定義 排序後位於最中間的數。如果長度為偶數則是最中間兩個數的平均值。n leq 10 5 a i leq 10 9 這個題水不水,就看你怎麼考慮了...

題解 P1168 中位數

看了此題,發現是求中位數,自然而然的想到了求kth 求kth有多種,我用的是權值線段樹,即記錄x的個數,但,我們看題,發現a i 可以高達1e9,乙個陣列是開不完的,不過萬幸的是n只到了1e5,而求kth只需要知道大小關係就行,不需要知道具體的值,所以,我們可以用離散化來搞定它!這裡說一下stabl...