從這里開始
- 比賽目錄
因為各種原因,所以沒有去。在場外和神仙 jerome_wei 當嘴巴選手,開心地發現我被打爆了。
題目大意可以在 ouuan 的游記里查看。
以下題解應該全是口胡的,應該有很多鍋,歡迎來 hack 或者交流做法。
6 個題,4 個大數據結構。Emm.....
聽說今年講題鴿掉了,沒進面試也有獎(
Day 1
Problem A
聽說是個聯賽水題,相信大家都會。
Problem B
大概 LCT 維護一下基環樹森林就行了。
誰愛寫誰去寫
Problem C
考慮這樣一個問題,把所有標號在 $[l, r]$ 中的點拿出來,任意兩個點之間有一條邊,距離為樹上的距離,求它們的最小生成樹,答案等於邊權大於 K 的邊數加 1。
有一個結論是,它的最小生成樹可以通過按深度排序,每個點在排在它前面的點中找一個距離它最近的點作為父節點的方法求出。
注意到對於每個點,考慮它和 MST 上父節點的邊什么時候會產生貢獻。顯然存在 $l', r'$ 使得,當 $l \leqslant l'$ 或者 $r \geqslant r'$ 的時候它會產生貢獻。
考慮怎么求解這樣一組數,注意到它們是相互獨立的,可以分開求解。
慮枚舉點 $p$,計算它的 $l'$,問題是求滿足下面的條件中的點 $x$ 中最大的標號
- $x < p$
- $dis(x, p) \leqslant K$
- 在按深度排序后,$x$ 在 $p$ 的前面。
然后這個硬做只能 $O(n\log^3 n)$。
考慮按深度排序以深度為第一關鍵字,標號為第二關鍵字,然后第三條就變成了 $dep_x \leqslant dep_p$。
考慮從小到達枚舉 $p$,用動態點分維護一下信息。考慮現在在分治中心要解決的問題,如果一個點從分治中心的子樹內跳進來,我們需要整個分治區域的信息,如果從分治中心子樹外跳進來,我們只用分治中心子樹的信息。
分治中心的子樹信息只用維護一下每個深度標號的 $max$。考慮子樹外對子樹內的信息怎么維護,你發現直接查詢非常困難,考慮子樹外對子樹內的影響,注意到子樹外每個點對子樹內的影響是對一段深度區間產生貢獻,這個可以線段樹維護。
對於求解 $r'$ 的過程是類似的,只不過最后一條限制變成 $dep_x > dep_p$,而不是大於等於。
剩下是個簡單掃描線。
時間復雜度 $O(n\log^2 n + q\log (n + q))$。
Day 2
Problem A
被全場打爆了,群除我人均會 T1,sad....
考慮只有 1 次操作,你需要最大化或者最小化 $s$,或者小於 0 的最大值和大於 0 的最小值。
考慮怎么維護這樣一個東西
最大值和最小值只用上面 4 個信息就能轉移。
所以現在的問題是怎么維護最后那兩個東西,一個顯然的想法是直接維護它們,但是非常顯然它是錯的。比如小於 0 的最小值在經過某次操作后大於 0,剩下那個值也大於 0,然后就沒法轉移了。
注意到每次 $s$ 或變為 $ks + b$,當 $k\neq 0$ 的時候,$|ks|$ 的絕對值總是不減的,因此每次操作至多使得絕對值減少 15($k = 0$ 的時候非常 trivial,可以直接判掉)。因此暴力維護 $[-225, 225]$ 之間的每個狀態是否可達,以及 $> 225$ 的最小值以及 $< -255$ 的最大值就可以轉移了。
復雜度 $O(2^n n V^2)$。
聽說只記最大最小除了 sub 1 全過了。
Problem B
支配樹模板題。
考慮求出每個點 $x$ 最早從哪個祖先 $f_x$ 能不經過根到它的路徑上的邊到達它。求法和求半支配點類似。只不過順序變成按從根開始依次遞歸 dfs 序較大的子樹處理。
現在考慮處理詢問,某個 $f_x$ 能夠到達的話,它的子樹內都能到。如果 $f_x$ 的深度比 $a$ 小,並且 $x$ 在 $b$ 的子樹內,那么將 $[in_x, out_x]$ 標記為可以到達的。如果一個在 $b$ 的子樹內點沒有被標記,那么它一定不可達,考慮用反證法,假設 $p$ 是深度最小的不滿足條件的點,考慮從根到它的某一條路徑,最后一個在根到 $a$ 路徑上的點 $q$,之后它不會再經過根到 $p$ 的路徑上的邊,然后我們得到了 $f_p$ 是 $q$ 的祖先,這和假設矛盾。
考慮在 dfs 序上離線處理詢問,如果一個點的 $f_x$ 比它的某個祖先的 $f_y$ 的淺,那么掃到 $y$ 的時候,$x$ 是否會產生貢獻取決於 $y$。然后可以用線段樹合並維護一個單調棧狀物,詢問的時候在線段樹上查一個區間和就行了。
Problem C
(原本這里還有點東西,因為奇奇怪怪的原因,所以它消失了)
考慮一下冒泡排序 $k$ 輪候的序列怎么快速求。依次掃描原序列,每掃到一個數就把它加入堆,如果堆的大小超過 $k$ 就 pop 掉其中最小值,並把它加入答案序列,最后 $k$ 個數顯然是最大 $k$ 個數從小到大排列。
考慮當 $q = 1$ 的時候怎么求答案,如果最后 $k$ 個數不滿足條件,答案為 0。否則考慮前面的數,每遇到一個數,如果它不是前綴最大值,只能將新加入堆的元素賦為它的值,因為堆內原來的元素都是大於當前前綴 max 的,如果是前綴 max,顯然隨便分配一個堆內的數給它就行了。所以答案是 $k$ 的前綴 max 個數次方。
現在考慮 $q \leqslant 5\times 10^5$ 的情形,有一個簡單 $O(n\log^2 n + q\log n)$ 做法,考慮點分治,處理跨過分治中心的詢問。是否合法可以判斷一下最后 $k$ 個的最大值是不是最大的,以及最小值是否比鏈上剩下的數大。先處理出每個點到分治重心的單調棧內元素個數,以及最大值。維護單調棧可以在插入的時候二分一下,記錄一下被修改的元素來做到簡單可持久化。然后求剩下一半的時候在求出的單調棧上二分一下就行了。
好寫好調好想,反正常數小,時限 4s,應該能過。
要做到只帶 1 個 log 考慮一下向上走的半邊可以每個點向祖先中第一個標號比它大的數連邊,然后倍增一下就行了。向下走可以考慮每個點有貢獻的條件,實際產生貢獻的開始位置大概也可以倍增求一下。
Day 2+
是湊個整齊而已,顯然這里不會有題解