• 沒有找到結果。

植物大戰殭屍2 Subtask 1

N/A
N/A
Protected

Academic year: 2021

Share "植物大戰殭屍2 Subtask 1"

Copied!
38
0
0

加載中.... (立即查看全文)

全文

(1)

建中校內第五次模擬賽題解

hansonyu123, Yihda Yol

(2)

植物大戰殭屍2 Subtask 1

• 直接線性做

– 複雜度 ,TLE 7分 – 喵

(3)

植物大戰殭屍2 Subtask 2

• 將詢問依左界排序。對於同樣左界的詢問 們,依右界排序。

– 每次都從某個左界開始,將右界由小到大依序 處理。對於一個左界,只需 (離散化)就 可以將所有右界處理完畢。

– 複雜度 ,TLE 26分。

(4)

植物大戰殭屍2 Subtask 3

• 將原序列每k個切成一塊

• 對於每個詢問,可以分成「完全包含區塊」

以及「不完全包含區塊」兩個部分

• 只需要預處理「區塊詢問」以及在每次詢 問時計算「渣渣們對答案的貢獻」即可

– 渣渣們對答案的貢獻需要由大區間內某渣渣出 現次數計算。這可以用vector儲存某值出現的 位置後,對該vector二分搜即可得到。

(5)

植物大戰殭屍2 Subtask 3

• 預處理區塊間詢問

• 對於每個渣渣,要 的時間計算貢獻

• 對於每個詢問,最多 個渣渣

• 總複雜度

– 取 時複雜度最小,為 – 這樣取的時候空間複雜度

– 注意這是在線作法喔

(6)

植物大戰殭屍2 Subtask 3

• TLE 63分

– 如果把常數壓超小,然後k取得好的話是有機會 AC的—by 吳聖福(?

– 要分case看渣渣裡的數字數量有沒有低於一個 限制,如果有的話用map一次記錄完會比較快

(7)

植物大戰殭屍2

• 前面的方法都有「一個一個放進去」的這 種feel,不如使用莫隊吧!

• 先離散化後可記錄當前區間某個數出現次 數。如此一來區間變化一後的答案很好算,

出現次數也很好維護。

• 直接莫隊,複雜度

• AC。

(8)

忍者調度問題

• 注意到對於同個主持人,出動愈多忍者愈 好。不妨對所有人,看看以他為主持人時

滿意度最大為多少,再將這些值取max即可。

– 問題轉化為,對每個點,詢問以他為根的子樹 中在權重和不能超過給定值M的條件下最多可 以取幾個點

• 30分的拿法就是對每個點都暴力地將他的 後代的權值由小排到大,再二分搜答案。

複雜度

(9)

忍者調度問題—整體二分搜

• 這次的解法很多,先從這次的範圍開始講

• 有N筆詢問,每筆都是一個二分搜,那試著 整體二分搜吧!

• 二分搜的對象從「選幾個點」改成「選權 值不超過某個值的點」

– 注意因為權重值可能相同,所以要把index放上 去以區別兩個權重值一樣的點,或者先將所有 人排序後以index為基準

(10)

忍者調度問題—整體二分搜

• 對於每次二分搜,可以用樹壓平計算答案 以決定要丟給左邊還是右邊

• 對於每個點,最多被二分搜 次,每 次被二分搜到的時候都需要modify一次線段

樹,故貢獻的複雜度

(11)

忍者調度問題—整體二分搜

• 對於每個詢問,最多被二分搜 次,

每次被二分搜到的時候需要query一次線段 樹,故貢獻複雜度

• 總複雜度 ,AC。

• 注意到就算每個點的總預算是分別給定的,

這個作法還是行得通。持久化線段樹也可 以AC,只是所需空間略大。

(12)

忍者調度問題—樹鏈剖分

• 接下來的作法都需要用到「總預算相同」

這個性質。

• 接著先講上次範圍的解法吧。

• 從權重最小的節點開始,看看如果他的祖 先都選了他的話會不會爆預算

– 可以證明如果某個點因為這樣爆預算了,那麼 他的祖先們也都爆預算了。

– 此外,加入這個點後被影響到的點只有他的祖 先們

(13)

忍者調度問題—樹鏈剖分

• 每次加入一個點的時候,先將他的祖先們

(含他)的值同加這個點的權重(路徑修 改),再看看這條路上第一個爆預算的點 在哪(路徑詢問),再把爆預算的點們的 值扣掉權重(路徑修改)。

• 問題被轉化為樹鏈剖分可支援的操作。直 接套用樹鏈剖分的話複雜度 AC。

(14)

忍者調度問題—啟發式合併

• 接下來的解法是從來沒教過的,不過他的 概念十分重要。

• 對於其中一個點,假設他的孩子們的答案 都已經計算出來,也知道要選哪些節點最 好了,那麼將這些節點全部加起來。如果 爆預算的話,要從權重最大的那個開始慢 慢移除,直到沒有爆預算。

– 一直移除最大:priority_queue

– 然而要怎麼樣將一堆priority_queue合併呢?

(15)

忍者調度問題—啟發式合併

• 如果有兩個priority_queue需要合併,一個 方法是將一個pq的元素一直拔出來放進另

一個pq裡。複雜度 。這引

導我們每次合併時,都選小的那個,一直 拔元素出來放進大的。

• 這樣做的話,對於每個元素,每次他被移 動時所在的pq大小至少會變兩倍,所以至 多被移動 次。因此總複雜度

– 此種技巧稱為「啟發式合併」。

(16)

忍者調度問題—可合併堆

• 事實上,有些堆可以支援「合併」這個操 作,就可以不用啟發式合併而得到更好的 複雜度。

– 以很威的費波那契堆為例,均攤O(1)插入、查 詢以及合併, 刪除。

• 最易實作的可合併堆為左偏樹。插入合併 以及刪除皆為

– 缺點為插入以及刪除皆建立在合併上,故常數 比priority_queue還要大許多(畢竟

priority_queue的常數很小)

(17)

忍者調度問題—左偏樹(Leftist Tree)

• 對於每個節點v,定義S(v)為從v往下走到虛 無(?)的最少步數。

• 左偏樹需要滿足兩個性質:

– 權重需滿足堆的性質

– 對於任何一個v,S(v->l) >= S(v->r)

• 這樣容易發現一些性質:

– S(v) = S(v->r)+1

– 以v為根的子樹至少有2 S(v) -1個點

(18)

忍者調度問題—左偏樹(Leftist Tree)

• 合併兩個左偏樹時,選擇根節點權重較大 的那個,並且將他的右子樹和另一棵左偏 樹合併。合併完之後記得檢查左偏樹的條 件是否滿足。若否,交換左右子樹。

– 複雜度 。由前面的性質即知

複雜度不會比 差。

– 因此「平衡的」左偏樹是一條鏈,「退化的」

左偏樹是平衡二元樹。

(19)

忍者調度問題—左偏樹(Leftist Tree)

• 插入就是把節點當一棵左偏樹合併。刪除 就是把左右子樹合併。

• 將啟發式合併改成左偏樹,即可獲得複雜

的解法。

(20)

尋找蘿莉第二彈 – EX

• Subtask 1-4 自己翻之前的題解吧

• Subtask 5 照參考資料用linked list做,複雜

(21)

尋找蘿莉第二彈 - EX

• 直接套treap照著參考資料做就可以AC了

– 每個節點維護當前區間max、「這個是否小於 等於下一個」,和當前區間是否有這種數

– 至於要維護前後樹的大小關係,可以用類似

「樹包linked list」的技巧(其實就是對每一個 節點都記它的前後元素的指標),並在split和 merge的時候好好維護就好了

– 或者在操作的時候硬搜也可以

• 複雜度

(22)

吐鈔機2 Subtask 1-4

• 這題的前四個subtask和最後一個的coding複雜度 完全不成比例

• DP,把吐鈔機按照可以買的時間排序

• 令dp[i]是在第 天賣出手上的機器後最多可以有 多少錢

,

(23)

吐鈔機2

• 化減 一下式子

,

,

• 可以看出這是個斜率優化,但是斜率 並沒有 單調性

• 維護凸包平衡樹

(24)

吐鈔機2

• 化減 一下式子

,

,

• 可以看出這是個斜率優化,但是斜率 並沒有 單調性

• 維護凸包平衡樹

(25)

吐鈔機2

• 千萬不要衝動刻treap(?

• 用set維護線段和交點

• 交點不能用浮點數,要用兩條線表達,不然 會WA掉

• 因為截距相乘會爆long long,所以才要用黑魔

• 複雜度

(26)

王老先生 Subtask 1,2

• 直接線性掃過去,複雜度

– TLE 21分

(27)

王老先生 Subtask 3

• 每次拍照就相當於區間加權。如果有Q棵線 段樹代表每個時刻每個人目前賺的錢,那 麼對每個人來說就可以直接二分搜了。

• 每拍一次照是一次修改,故可以考慮使用 持久化線段樹。

• 區間加值用懶人標就可以支援了。

• 時間複雜度 ,空間複

雜度 。WA/TLE 45分。

– WA原因:區間加值加到重複的人就會爛掉。

(28)

王老先生

• 持久化線段樹差一個小問題就過了。不妨 試著使用整體二分搜解決問題。

• 對於同一個人管理的不同田地以及一次拍 照區間[L,R],不妨將貢獻全歸給落在[L,R]中 最左邊的那個田地。

– 對於某個田i,假設下一個和他同個主人的田在j,

那麼會使i有貢獻的區間[L,R]要滿足L<=i以及R<j。

• 每次二分搜時相當於在解決一個二維查詢 修改問題,故將其中一維排序以達成降維。

(29)

王老先生

• 對拍照的區間以及田地貢獻區間的右界分 別排序即可使用BIT處理前述二維問題。

– 不是出現第一次了,所以就不仔細講了。

• 因為每次二分搜時是「離線」而不是「在 線」,所以資料結構內的東西不能遞給下 次二分搜。不過可將目標扣掉現階段賺的 錢當作新的目標,遞給下次二分搜。

• 總複雜度 ,AC。

(30)

最小公倍數 Subtask 1

• 聽說這個時候不會爆long long

• \直接線段樹/

• 複雜度

• 其它subtask會因為時間比較緊而TLE、因 overflow而WA。模完後再最小公倍數也會 WA(廢話)。

(31)

最小公倍數 Subtask 2

• 直接將答案的質因數分解式求出

– 對每個質因數來說,都是一個RMQ問題

– 用sparse table有記憶體問題,故使用線段樹

– Tip:用一棵線段樹存多個值比用多棵線段樹還要 有效率(可避免遞迴次數過多)

• 複雜度 ,MLE 23分。

(32)

最小公倍數 Subtask 3

• 對於大於 的質因數來說,只有0次或1次 兩種可選。

– 故在意的只有區間中有無該質因數的倍數。區 間變動1的時候很容易維護,故考慮使用莫隊。

– 區間加入/刪除的數最多只會和一個大於 質因數扯上關係,故莫隊的複雜度夠快。

(33)

最小公倍數 Subtask 3

• 對大於 的質因數使用莫隊,小於 的質 因數則維持使用線段樹(用莫隊的負擔有 點大)。

• 總複雜度

MLE 54分。

(34)

最小公倍數

• 首先對所有詢問的右界排序:

• 假設當前要齁住的是右界是r的詢問們。對 於所有i<r,知道b[i] = query([i,r))/query([i+1, r))就可以用線段樹或BIT之類的處理區間乘 積知道query([i,r))了

(35)

最小公倍數

• 重點就是 r遞增的時候要怎麼維護b[i]。

• 只要注意到對於一個質數p和一個數i,b[i]

的p的冪次變化的話,代表a[r]的p的冪次比 a[i+1]到a[r-1]的p的冪次都還大。

• 對於每個質數p,可以用一個單調隊列(嚴 格遞減)維護p的冪次數。每次r++時只要用 a[r]的質因數冪次數更新top,之後再看看

a[r]是不是比top大,是的話就把top拔掉繼 續更新,否的話就推入stack。

(36)

最小公倍數

• 可以證明這樣變化次數是 ,其中 是2*3*5*7*...的反函數。因為這裡處理的均 攤複雜度O(1)(當然質因數分解

要先做好),所以複雜度

(37)

最小公倍數

• 對於每次b[i]的變化,一定都是把b[i]除掉某 一個東西。所以這裡的更新可以用線段樹

或者是BIT處理。因為更新次數是 所以複雜度 。然後就把右界

是r+1的詢問們一次問完。

• 總複雜度 ,AC。

(38)

最小公倍數 大陸人看法

• 其實可以用某種神奇的方法變成跟王老先 生的子問題差不多的問題

– 對於每個數,都拆解成質因數分解式。對於每 個質因數p^k,在他原本的位置寫上p,p^2, …, p^k。

– 把同一個數當作同一個主人,然後某個p^i被考 慮的時候都貢獻p。區間最小公倍數就是新區間 的所有人的貢獻(同一個主人的數不重複計

算),所以可以用類似王老先生整體二分搜的 方法做。

• 複雜度估計略,不過和前種方法相去不遠。

參考文獻

相關文件

在相隔 80 公尺的兩根電線桿中間,每隔 20 公尺種榕樹一 棵,在兩棵榕樹之間種椰子樹 3

  如來一代時教。始自道場。迄乎雙樹。其間頓漸權實之部。偏圓半滿之談。於法

順伯為測量樹高 ¯  CD ,站在距離樹 30 公尺處,即 E 點的位置,將其手臂伸直,把一支有刻度的 尺豎在眼睛前方,若順伯的眼睛 O 點,和尺上的 A 點及樹的頂端 D

啄木鳥醫生看看四周,馬上明白了小樹哭的原因。小樹又

本篇選讀的是〈逍遙遊〉最後二段,惠子先後以大葫蘆與大椿樹為例,比喻

 這兩棵大榕樹或許生長了幾十年才換來高大的樹杈,深埋在地裡的長

的 Midgard,一條伸向“巨人國度”的 Jotunheim 以及一條延伸到“死人之國”的 Niflheim。 而

因為我們的學員年齡層是大概 75~80 歲左右,那這些中高齡(老師)的來跟