
contents
Problem
背景
在 2015 年 6 月的 Facebook 上,不少以「靠北」為前綴命名的粉絲頁面,就如 靠北工程師 為例,不少業界工程師匿名在上面抱怨工作過時、主管、生活 … 等。突然有一篇 #靠北工程師7257 抱怨著編程競賽的零零種種,從回應中能明白存在業界工程師不清楚編程競賽,以 UI 介面、cmd 指令 … 等方式理解比賽的目標、運行。
網路處處有答案,演算法和資料結構到底重不重要?抄下來能用就行,大部分的要求是不講求效率的,但對於曾經在編程競賽待過一陣子的小夥伴而言,看到他們的理解方式開始感到憤憤不平,進行了一陣子的爭吵。
過一陣子,大批的學生開始進入 靠北工程師 裡發文,開始爭論學校、系所哪個是比較有未來的,突然間有一位資管系的同學發問這一道算法題 #靠北工程師7780 ,結果一不小心就看錯題目,把種類數誤看成個數,於是討論了不少其他的算法來完成,現在就把這個問題交給你。
用各種算法解決這個誤解的題目。
問題描述
Autumn 和 Bakser 又在研究 Gty 的妹子序列了!
但他們遇到了一個難題,對於一段妹子們,他們想讓你幫忙求出這之內美麗度 $s_i in [a, b]$ 的妹子個數。為了方便,我們規定妹子們的美麗度全都在 $[1,n]$ 中。
給定一個長度為 $n$ ( $1 le n le 100000$ ) 的正整數序列 $s$ ($1 le s_i le n$),對於 $m$ ( $1 le m le 1000000$) 次詢問 $l, r, a, b$,每次輸出 $[s_l, text{… },s_r]$ 中,權值 $s_i in [a, b]$ 的個數。
Sample Input
|
|
Sample Output
|
|
Solution
相較於 b414. BZOJ 3809 Gty 的二逼妹子序列 解法會相對多樣,單純計數就會變得比較簡單。
在這一題中,這裡提供三種解法:
- 莫隊算法
只能離線處理,無法強制在線詢問,算法複雜度由分塊降到 $O(N^{1.5})$。可參考 b414 的解法。 - 掃描線 + BIT
只能離線處理,把題目轉換成二維情況 $(i, A[i])$,詢問相當於找到矩形內部 $[l, r] times [a, b]$ 有多少點座標,所以可以當作二維前綴來完成計數 $f(l, r, a, b) = f(r, b) - f(l-1, b) - f(r, a-1) - f(l-1, a-1)$。$f(x, y)$ 表示從原點 $(0, 0)$ 到 $(x, y)$ 的點數量,這樣的方式記憶體過多,利用掃描線算法降下來,對 x 由小掃描到大,依序將點插入詢問 $f(x, y)$ 會在掃瞄到 x 時,詢問 $[0, y]$ 之間的累計個數得到,最後將每一個詢問離線成四個詢問,掃描一次即可。 - 可持久化線段樹
必須預處理,支持在線詢問,不帶操作修改。將序列權值排序 $(A[i], i)$,依序索引值插入線段樹,紀錄每一個插入完的線段樹狀態,接著當詢問 $l, r, a, b$,相當於在版本ver_b - ver_a查詢線段樹區間 $[l, r]$ 的總和。由於是計數符合區間減法才能這樣做,否則持久化線段樹還要套別的小技巧來完成。
補充一點,雖然 KD-tree 效能是 $O(sqrt{N} + K)$,它也支持 range searching,但必須搭配 report K 操作,那個 $O(sqrt{N})$ 的花費是伴隨著 report 存在,因此單一筆計數詢問是無法達到 $O(sqrt{N})$,天真的我寫下去直接 TLE。
莫隊算法
|
|




近期评论