or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
整體二分
顧名思義 : 全部的二分搜一起做就叫做整體二分,可以用來求區間第\(k\)小。
區間第\(k\)小也可以用另一個方法做 : 持久化線段樹
用二分搜求整個數列的第\(k\)小
假設質域最大到\(C\),那就可以用\([1,C]\)來二分搜,如果\(k\)比序列中小於等於\(mid\)的數量小,代表第\(k\)小的數字會小於或等於\(mid\),就往左搜,否則往右搜。
pref[i]為有幾個數比i小,可以先預處理 :
pref
如果有很多個query呢 ?
那就全部一起做,初始\(l,r\)都是\(1,C\),每做一次每個查詢的範圍都會除以\(2\),並維護每個查詢的左右界,直到\(l=r\)。
遞迴版本 : 把要往左子樹遞迴的綁成一堆,往右子樹遞迴的綁成一堆,分別遞迴。遞迴到底的時候代表這組\(Query\)的答案就是\(l\)或\(r\)。
那如果每個\(Query\)都有範圍限制呢 ?
在查詢的時候就不是用\(pref\)了,因為預處理的時間複雜度及空間複雜度沒有很好,所以就直接在當下計算區間中有幾個數比\(mid\)還小,因為要計算區間合,我們就可以使用差分的概念,差分要用到前綴合,為了可以快速計算前綴合,還要使用到BIT。
實作
在每次遞迴的層中,先把<=\(mid\)的數字的位置update到BIT裡,也就是在\(pos\)的位置+1,這樣在求區間\([l,r]\)<=\(mid\)的個數時就可以用\(pref[r]-pre[l-1]\)的方法來計算,因為被update進去的都是<=\(mid\)的數字,加上BIT的前綴合功能,可以很輕易地得知在前綴中有多少數字<=\(mid\)。
在決定要往左或往右遞迴後,另一邊的數字(假設往左遞迴的話,就是>mid的數字)就不會再被用到,可以只遞迴該邊的數字即可,節省時間。
回圈版本 : 只能用在更新要照順序時