JOI Final 亂做


LOJ3256「JOI 2020 Final」火災

顯然區間詢問可以變成前綴詢問。

從左往右枚舉右端點,維護單調棧,嘗試維護每個 \(T\) 的答案。

但是對於一個位置,它往前的后綴最大值個數是 \(O(n)\) 的,所以不能暴力。

按照套路,在一個后綴最大值被彈掉的時候計算它的貢獻,那么在詢問的時候就只需要考慮在棧里的元素即可。

對於 \(r-i<T\) 的元素只有 \(i\) 最小的那個元素有可能有貢獻,而再靠前的元素的貢獻可以把 \(pre_r \to r\) 的樹建出來之后 dfs 的過程中維護點到根的信息。其中 \(pre_r\) 是前面第一個大於 \(r\) 的位置。

LOJ3013「JOI 2019 Final」硬幣收藏

不可能會貪心的,這輩子都不可能會貪心的

先把每個硬幣沿着最短路移到矩形內部,這樣顯然不劣。

然后在矩形內部有 \(2n\) 個球和洞要兩兩配對。顯然可以看做球和洞一起移動。

從左往右貪心。考慮最左邊的兩個格子,把在同一位置的球和洞匹配掉(顯然不劣)之后:

  • 上下都只有洞,那么都往右走。
  • 上下都只有球,同樣都往右走。
  • 一邊有球一邊有洞,不妨設上球下洞,球>洞。如果洞沒有被這里的球匹配完,那么就有右邊的球走到洞里,這里的球往右邊走。可以調整為這里的球往下走,右邊的球往上走,代價不變。

所以在第三種情況中,可以直接用球把洞匹配完,然后把球往右移。

進行 \(n\) 步這樣的操作即可得到答案。

LOJ3014「JOI 2019 Final」獨特的城市

我的想法:

顯然,對於一個點,合法的城市全都在它到它的最遠點的路徑上。而最遠點只能是直徑端點之一,所以把兩個端點分別提為根做一次。

那么此時一個點就只需要關心它到根這條路徑上的點了。

這條路徑上哪些點是合法的呢?把 從這條路徑上的點開始的往下的路徑 往上拍,沒被拍到的點即為合法的。

在 dfs 的時候維護這個過程。dfs 到 \(x\) 的時候,用一個棧維護路徑上所有合法點對應的顏色,每個顏色只記錄最淺的位置(因為最淺的位置最不容易被刪掉),棧內顏色按最淺的位置的深度排序。

為了求 \(x\) 的答案,只需要二分求棧內深度較淺的不會被子樹拍到的顏色有幾個。

dfs 進某一個兒子的時候,把其他兒子的子樹往上拍的考慮進去,會把棧里的元素彈掉一些,也可以二分求出位置。然后要把自己的顏色嘗試加進去。

那么又有一個問題:我怎么知道我的顏色現在是否還在棧里呢?

對每一個顏色記錄它在棧中的位置即可,如果位置 \(\le\) 棧的大小那么說明在棧中,否則不在。

加入 \(x\) 的時候會使棧的大小加 1 ,要把原來在這個位置的顏色標記為不在棧中,即把它在棧中的位置定為 \(\infty\)

回溯的時候撤銷所有操作。

題解做法:

前面基本上是一樣的,還是在於怎么求鏈上合法的不同顏色個數。

用棧維護沒被拍掉的點,用桶維護每種顏色的出現次數。

長鏈剖分,先往重兒子走(用輕兒子的最大深度彈棧),再往輕兒子走(用重兒子彈棧)。

然后復雜度就對了?就對了?就對了?你在玩我?

如果按我的想法,每次 dfs 之后還撤銷,那么復雜度顯然是不對的。

但是注意到一個性質:如果往一個兒子走,子樹內的鏈把自己的祖先拍掉了,那么往別的兒子走的時候這些祖先還是要被拍掉的,也就是說它們已經廢了。

所以是不用撤銷的,只需要 dfs 一個兒子后再把自己加進去一次即可,因為自己是不一定要被拍掉的。

總入棧次數是 \(O(n)\) 的,所以復雜度 \(O(n)\)

LOJ2335「JOI 2017 Final」足球

最怕這種看起來莫名其妙的題了……

不學OI的同學總覺得這種題是最好做的

在最優解中,如果一個人曾經控過球且現在沒有控球,那么以后都不可能控球。證明是因為運球和空跑的代價是一樣的。

然后我就不會了啊啊啊啊……

可以猜到這么一個做法:把每個位置拆點,分別表示 沒人控球、有人控球、在往上/下/左/右飛 ,然后沒人控球向有人控球連的邊權為 \(C\times 最近的人\) ,跑最短路。

容易發現最優解一定被包含了,但是怎么證明這樣跑出來的方案合法呢?具體而言,怎么保證一個人不會產生分身,跑去一個地方踢了一腳,瞬移回原來位置,又去另一個位置踢了一腳呢?

沒看到哪里有證明,於是自閉了……

Rose_max 老大給了個證明,不過看不太懂,所以棄了。

LOJ2336「JOI 2017 Final」繩

由於染色的代價和厚度有關,所以可以發現折完再染不如一開始就染好。

考慮一個顏色序列什么時候合法。顯然只能有兩種顏色。

在每一次折的時候,要么是把邊上的顏色連續段長度減 1 ,要么是把對稱點所在的連續段長度砍半,且變到邊上去,較短的那一邊刪掉,其他連續段不變。

所以初始狀態除了兩端的連續段長度都必須是偶數,並且容易證明這是充要條件。

然后這個條件也就等價於對於我們重點關心的那個顏色,每一段長度為偶數,且起始位置的奇偶性相同。

所以對於每一種顏色,枚舉起始位置的奇偶性,判斷每一段是否要往前/往后生長(可以發現此時即使兩段合並了也沒有問題,因為不可能重疊),然后在剩下的格子里挑出現次數最多的顏色和它一起。

怎么除了第一步以外每一步都想不到啊 /kk

LOJ2345「JOI 2016 Final」領地

先特判掉一個周期走回原地的情況。

否則,相當於是這個路徑每次會向着一個向量的方向平移,最后得到許許多多的路徑的交。

把只靠這個向量就可以互相平移到的格子設為一組,每組分別做。顯然對於所有組的格子,邊界上的被初始路徑經過的點數之和是 \(O(n)\) 的。

對於這一組格子,把四個角的被標記的點分別拿出來,然后一個點會覆蓋后面連續 \(K\) 個位置,可以變成 \(O(n)\) 個線段,最后再用歸並把這 4 組線段求個交即可。

以上是口胡,因為網上沒看到有題解。

LOJ2346「JOI 2016 Final」斷層

直接維護看起來莫名其妙的,考慮把最后在地面的位置標記一下,倒着做,維護它們原來在哪里。

手畫一畫就會發現,好像此時每次操作都是對一個前綴/后綴進行操作。

證明:

  • 對於操作 1 ,一個點會往左下滑當且僅當 \(x-y\) 較小,操作結束后被操作的點 \(x-y\) 不變, \(x+y\) 減小。
  • 對於操作 2 ,一個點會往右下滑當且僅當 \(x+y\) 較大,操作結束后被操作的點 \(x+y\) 不變, \(x+y\) 增大。

在初始情況下,點的 \(x-y,x+y\) 都遞增,所以任意時刻都是遞增的,任意操作都是對一個前綴/后綴進行。

所以就線段樹維護一下坐標即可。

LOJ2727「JOI 2015 Final」舞會

顯然可以二分答案,變成 01 串。顯然編號沒有任何用。

考慮操作的過程,相當於每次把最靠前的三個合並成一個丟到最后面去。

一開始模擬一下這個過程,把合並出來的作為三個的父親,即可建出一棵樹。

在樹上設 \(dp_x\) 表示讓 \(x\) 子樹合並出一個 1 要多少個 1 即可。

LOJ2760「JOI 2014 Final」裁剪線

第一眼看上去好像毫無思路,於是考慮掃描線。

從上往下掃,維護被豎線分開的段之間的連通性。

加入一條豎線的時候,把一個段分成兩個段,但這兩個段是連通的。

刪除一條豎線的時候,把相鄰的兩個段合並,相應的連通性也可能會改變,用並查集維護即可。

加入一條橫線的時候,會把一個區間的段刪除,換成新的和別的段都不連通的段。其中刪除的段中每有一整個連通塊被刪除則答案加一。

朴素地做好像是 \(O(n^2)\) 的。

把加入橫線時加入的段設為 “平凡的” ,加入或刪除一條豎線的時候影響的段設為 “特殊的” 。

顯然特殊的段的個數是 \(O(n)\) 的,而加入橫線的時候可以很容易把平凡的段的貢獻算上,對於特殊的段暴力統計,並且特殊的段被橫線刪掉后就會變成平凡的。

所以數據結構維護一下即可做到 \(O(n\log n)\)

以上都是口胡,網上只看到一篇題解,不過思路似乎是這樣的。

LOJ2765「JOI 2013 Final」 冒泡排序

好像和這個基本一模一樣。

顯然交換之后的代價就是逆序對數;顯然在特判掉原本就有序之后,如果交換 \(i<j,h_i>h_j\) ,那么貢獻是 \(1+2\sum_{k=i}^j [h_j<h_k<h_i]\)

所以 \(i\) 一定是前綴最大值, \(j\) 一定是后綴最小值。

此時可以證明決策單調性,用分治+主席樹在 \(O(n\log^2 n)\) 的復雜度內做出來。

然而另一個做法更暴力也更快……

對於一個點 \((x,h_x)\) ,可以求出哪些 \((i,j)\) 會包含它,顯然是個矩形。

那么用掃描線即可得到矩形覆蓋的最大值,\(O(n\log n)\)

這篇博客終於更完了……


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM