BZOJ2653 middle 主席樹 二分

2021-09-28 15:23:14 字數 2017 閱讀 7592

無法確定中位數 ? 我們可以考慮轉化思路。

二分乙個中位數,再判斷是否合理。

根據本題中中位數的定義,只需要小於 它的 數的個數≤∣l

en2∣

\le ||

≤∣2len

​∣。我們可以將大於i

ii的數賦值成1

11,小於的賦值成−1-1

−1。若ma

xlsu

m[a,

b−1]

+sum

[b,c

]+ma

xrsu

m[c+

1,d]

≥0

若maxlsum[a,b-1]+sum[b,c]+maxrsum[c+1,d]\ge0

若maxls

um[a

,b−1

]+su

m[b,

c]+m

axrs

um[c

+1,d

]≥0,i

ii可能可以更大。

如何實現賦值操作 ? 用主席樹增量法更改。

從小到大排序,對於「下乙個數的主席樹」,把當前數從1

11改為−1-1

−1即可。**好懂。

#include

#define pf printf

#define sf scanf

#define cs const

#define ll long long

#define db double

#define ri register int

using

namespace std;

#define in red()

inline

intred()

cs int n=

1e6+

10,m=

2e4+10;

#define lc(x) ch[x][0]

#define rc(x) ch[x][1]

int ch[n][2

],rt[m]

,n,m,tot=0;

struct nodeval[n]

;inline node merge

(node a,node b)

inline

intcpy

(int x)

inline

void

build

(int l,

int r,

int&t)

inline

void

insert

(int p,

int l,

int r,

int k,

int&t)

inline node query

(int p,

int l,

int r,

int ql,

int qr)

typedef pair<

int,

int> pi;

#define fi first

#define se second

pi a[m]

;int q[4]

;inline

bool

check

(int k)

inline

intrun()

return

check

(r)? r : l;

}signed main (

)sort

(a+1

,a+n+1)

;build(1

,n,rt[1]

);for(ri i=

1;i<=n;

++i)

insert

(rt[i],1

,n,a[i]

.se,rt[i+1]

);m=in;

int ans=0;

while

(m--

)return0;

}

bzoj2653 Middle 二分 主席樹

這題厲害啊。根本想不到。據說是clj的題?首先要想到二分答案,想到就解出一半了。假設有乙個值x,如果x是區間 l,r 的中位數,且l a,b r c,d 那麼答案一定 x 否則答案一定 那麼如何判斷x是否是 l,r 的中位數呢?實際上,如果使用二分的話,我們不需要知道x是否一定是 l,r 的中位數,...

BZOJ 2653 middle 二分 主席樹

乙個長度為n的序列a,設其排過序之後為b,其中位數定義為b n 2 其中a,b從0開始標號,除法取下整。給你乙個 長度為n的序列s。回答q個這樣的詢問 s的左端點在 a,b 之間,右端點在 c,d 之間的子串行中,最大的中位數。第一行序列長度n。接下來n行按順序給出a中的數。接下來一行q。然後q行每...

BZOJ 2653 可持久化線段樹

對於中位數有乙個性質,將所有大於等於他的數置為 1 小於他的數置為 1 則所有數的和 0 或 1。單調性還是很顯然的,因此我們二分答案,若對陣列求和答案大於等於 0 則當前答案可行。定長的區間我們已經會求解中位數了,現在的問題是,左端點在 l 1,r1 右端點在 l 2,r2 如何找到中位數。此時我...