Author: toxicpie
Setter: erd1
題目:給定棋盤上皇后的位置,請輸出有多少對皇后互相攻擊。
暴力枚舉兩個皇后,再枚舉有沒有第三個皇后擋在他們中間。
複雜度:。
維護四個 map
,每個代表第 key
個直(橫、斜)排有 val
個皇后。
答案就是 。
複雜度:。
抱歉卡了點常數。 ><
畢竟肥的 跟瘦的 大概差了七八倍的常數,所以官解跑 秒,時限開 秒似乎還是卡到了很多人。
順便讓各位練習全國賽被垃圾題卡常的心態調整(X
官解的做法是把輸入的 存在四個陣列裡面,然後 sort
,答案就是四個陣列的 v.end()-unique(v.begin(), v.end())
的和。 當然,胖一點點可能還是能過,但是開到 set
或 map
或 lower_bound
太多次就會太胖。
複雜度:。
注意到 unordered_map
(或 cc_hash_table
等)的複雜度只有在輸入是隨機的時候才是平均 的。在輸入不是隨機的時候,除非自己給雜湊函數,否則很容易被弄到每次插入 。理論上這連第二個子任務都不應該過但是我好像有卡失敗QQ。
Author: HNO2
Setter: double
題目:給定一張有向無環圖,請判斷是否有一條哈密頓路徑。若有,請輸出一個。
枚舉所有可能的路徑,再檢查相鄰兩項有沒有邊
可以觀察得到 DAG 上的 Hamilton 路徑存在若且唯若拓樸排序唯一,此時的拓樸排序就會恰為其 Hamilton 路徑,於是 求出拓樸排序並檢查即可。
Author: SorahISA
Setter: casperwang
題目:給定一個矩陣,請計算有多少個十字形區域滿足左右臂等長,上臂比下臂短,且最大值發生在交叉點。
只要考慮上下的情形即可,對每個權重大於左右兩邊的中間位置,用單調隊列找出一個位置可以分別大於上下的多少格並用 Subtask 5 的算式計算答案。
對每個位置, 暴力找出可以分別大於上下左右的多少格,令其個數分別為 、、、,接下來就以下面算式 計算出答案。
總複雜度是
期待看到神奇的唬爛作法(?)
用單調隊列找出一個位置可以分別大於上下左右的多少格,並以 Subtask 2的方法計算答案。
計算答案的公式可以優化如下
總複雜度是
Author: SorahISA
Setter: SorahISA
題目:有 輪猜拳比賽,請構造出一個循環出 個拳的方法,使得可以贏過固定出拳的對方,且 盡量小。有 筆測資。
限制:;。
既然 ,那出的拳只會有三種可能,只要分別計算出剪刀、石頭、布分別會得幾分就可以 AC 了!
時間複雜度:。
限制:;。
對於一組給定的拳,顯然你可以在 時間得出他的分數:
所以只要枚舉所有出拳的方法就可以 AC 了!
時間複雜度:。
限制:。
觀察出愛一個位置 的拳 只會對應到天衣 的拳,匹配的位置都是固定的,所以能先處理出在位置 出三個拳會得到的分數 、、 再進行後續的運算。
現在題目被簡化成如下的樣子:給你 個三選一,分別可以獲得 、、 分(),請問要讓總和 的總和最小值是多少?
是經典的背包題,透過 DP 來處理可以組成的數字。令 代表前 組的所有 種可能性中存不存在可以達到 分的取法,有轉移式
最後就 找到最小的位置 使 再把解回溯回來就好了。
請記得處理邊界、超出範圍的問題,且要把 陣列平移 格,因為你也會需要負數的位置。
時間複雜度:。
上面 DP 的轉移式是經典的湊數字背包問題,可以使用 來優化。因為只是語法問題,所以直接上 code:
時間複雜度:,在這裡 是 。
去年的全國賽也有需要使用 來優化的題目,可以參考看看 >////<。
Author: erd1, double
Setter: enip
Statement: joylintp
題目:有一些組別在排隊,有兩種操作:
要怎麼知道第 個人是誰呢?首先我們要找到第 個人在第幾組。這可以用 BIT / 線段樹之類的作到。
接下來,我要知道,對於這一組,它被旋轉了幾次。然後我們可以發現,對於同樣長度的隊伍,被旋轉的次數是一樣的。因此我們只要對每個長度 都知道它被旋轉了幾次就好!而這東西也是 BIT / 線段樹可以解決的事情。
操作 2 的時候,就是對兩個資料結構單點/區間加值之類的,取決於你用了哪種資結。
Author: HNO2
Setter: HNO2
題目:給定一棵有根樹,這棵樹不計根節點一共有 個葉子。每個葉子 有一個數字 ,其中 必定是 的祖先。建一張 個節點的新有向圖,其中 有連邊若且唯若 同時是 和 的祖先。問新圖有沒有一條哈密頓路徑,如果有的話輸出任意一條。
注意到葉子數量很少,所以可以暴力找出新圖有哪些邊以後,再對新圖做哈密頓路徑的位元 DP。
找新圖的邊的部份可以使用對每個 做一次 DFS、對每個點暴力找出所有祖先後再判斷,或其他 的作法也可以。當然其他時間複雜度更低的作法也可。
找哈密頓路徑的部份是經典問題,可以在 的時間內做完。
這個 Subtask 以後需要用到一個性質:如果原問題有解,則一定有一個解是將所有葉子依照某個 DFS 順序而成。(簡略說明見下方)
因此可以發現對於定根 來說,最多只有一個子樹,他的所有葉子走完以後無法回到 或他的祖先,而這個子樹要留到最後再走。而根據這個 Subtask 的限制,沒有與 建邊的子樹就是無法回到 或他的祖先的子樹(可以稍微想一下),因此就可以據此找出一個合法的順序了。
有了上面那個性質以後,可以發現最多只有一個子樹,他的所有葉子走完以後無法回到 或他的祖先。所以對於每個子樹我們想要找出走完這棵子樹以後可以走到的最淺深度。
使用樹 DP。令 為 的深度,且令 為繞完這棵子樹後可以回到的最淺深度。轉移如下:
要構造一組解也十分容易,記住哪個子樹要最後走以後,剩下的子樹依照任意順序繞即可。時間複雜度為 。
考慮給定根 底下的所有葉子順序,令 是一個合法的順序。假設兩個不相交葉子區間 都隸屬於同一個子樹,且兩個區間都和他們相鄰的葉子都屬於不同子樹的話,那把兩個區間併起來,其他相對順序都不動也會是合法順序。這是因為 和 屬於不同子樹, 必為 的祖先,故也能抵達 。用同樣方式也能證明其他接口起來是好的。
這樣持續交換下去就能讓同一棵子樹底下的葉子全部併在一起。之後對每個子樹遞迴做下去就是一個原樹的 DFS 順序了。
Author: erd1
Setter: erd1
題目:已知區域的地形分布是帶狀的,在每一個區域的移動速率是定值。請問兩點之間的(時間)最短距離。
距離除以速度加起來不虧。
複雜度 。
路徑一定是在地形交界處轉折,而且轉折點對時間的函數是凸(或凹)的。
因此可以對他三分搜。
複雜度 。
這題其實是物理題。司乃爾定律告訴你最短路徑一定滿足 是定值。對起始角或起始 或隨便什麼的做二分搜牛頓迭代都會過。
複雜度 。
最後是精度問題。
你只要想像如果有一塊的速度超大,其他都超小,那你在其他段的路徑應該幾乎是平的,然後只有在那一段超斜。所以如果你在其他段的角度稍微動一下,你在那段的角度應該會動超級多,然後你就噴掉了。
對最斜的那段的角度二分搜也是沒用的,因為你的角度會很接近 ,所以角度稍微動一下,你的 也會動超多(你可以看看 的函數圖形),他還是會噴掉。
因此正確的做法應該是求出 。你可以證明 只需要 的精度左右即可。
Let , then the answer is given by
To calculate the root to a precision of , we may implement a binary search to do so in . However, to calculate the answer to a precision of , we would need a precision of in the worst case, which is not desirable.
你只要想像如果有一塊的速度超大,其他都超小,那你在其他段的路徑應該幾乎是平的,然後只有在那一段超斜。所以如果你在其他段的角度稍微動一下,你在那段的角度應該會動超級多,然後你就噴掉了。
對最斜的那段的角度二分搜也是沒用的,因為你的角度會很接近 ,所以角度稍微動一下,你的 也會動超多(你可以看看 的函數圖形),他還是會噴掉。
因此正確的做法應該是求出 。你可以證明 只需要 的精度左右即可。
Suppose is descending, and .
We ought to calculate
Thus if has an error of , has an approximate error of
And thus
Which could skyrocket when .
The same thing occurs if is in terms of :
And thus
Which still wouldn't work when is small enough.
Now suppose is terms of .
You could already see that the 's should cancel out the 's, with 's remaining, so that the reasoning above does not show that it skyrockets.
And indeed
Thus to obtain the answer with a relative precision of , it suffices to calculate to a relative precision of about .
Given , .
is then given by
A potential culprit of numerical instablility is the subtraction, but by expanding the term,
This can still be calculated presicely (as are integers).
Author: toxicpie
Setter: toxicpie
題目:給 顆雞蛋的顏色、被生下的時間以及美味程度,限制每兩次吃雞蛋要間隔 秒,求在 秒內吃恰好 顆黑雞蛋和 顆白雞蛋的最大美味程度總和。
只要能吃到 顆蛋,那答案就是 ,否則是 。因為每顆蛋都長一樣,所以在某個時間點如果有蛋可以吃,那先吃一顆不會虧。
的暴力模擬不會過,不過我們可以把雞蛋按照 排序,然後重複做以下的事:
時間
對於任意的吃蛋方案,我們可以把所有吃蛋時間盡量往後推,變成在 時各吃一顆蛋(如果再晚的話會來不及吃完)。這時我們發現在每個時間點吃蛋時,如果沒有蛋可吃那答案是 ,否則選擇目前美味程度最大的吃一定不虧。
把 排序之後可以維護一個美味程度的 set 或 priority queue 來做事。
時間
假設有某種方法可以吃 顆黑雞蛋和 顆白雞蛋。考慮該方法,但每次吃蛋時,我們改為吃同樣顏色的蛋中生下時間最早的。到最後,我們吃的蛋的集合一定是 最小的 顆黑蛋和 最小的 顆白蛋。所以只考慮那些蛋,然後用 Subtask 1/2 的做法即可。
時間
考慮 Subtask 2 的做法,但是分成兩個版本:
如果以上的答案都不是 且 ,那答案是 ,否則答案是 。
這邊用到的性質可以在下面的 Proofs 找到。
時間
Subtask 2, 3 的順序和分數好像應該要互換?
令 為總共吃 顆黑雞蛋和 顆白雞蛋時,美味程度總和的最大值。我們要求的是 。
如果 沒有定義,那答案就是 。
由 Subtask 3 可以知道,如果 和 都有定義,那 , 都會有定義。也就是說, 有定義的地方是某些連續的非負整數。
直接求 可能十分困難,但求 的最大值很簡單 (Subtask 2)。如果 在有定義的地方是凹函數,那可以用傳說中的 Aliens trick,也就是二分搜一個 滿足 ,而此時的 即是答案。
的最小值求法就是把所有的白雞蛋美味程度加上 ,然後做 Subtask 2。
時間 ,其中 是美味程度的最大值。
TBA
Author: erd1, HNO2
Setter: erd1
題目:給定一棵樹,每個點上面有水。每次詢問是戳一個點,所有點的水匯往該點走一步,並輸出點上原有的水量。
暴力模擬。。
暴力模擬。只要遇到沒水的點就直接break
掉。但是一開始水可能不聯通,所以這樣會 WA。你只要初始化時給每個人一個 的水就好(或官解是拿pair<int, bool>
)。
因為樹是隨機生成的,你去估計每個人的深度總和你會發現他是均攤 的。
拿 treap
暴力模擬。 。
先假設一開始的水都是連通的而且每次一定會戳出水來。有水的區域一定是一個連通塊 。在子圖 上對所有的鏈(一串度數至多 的點)開一個 treap
維護。每次花 暴力 dfs 那個子圖(對每個鍊跟每個練的交會處暴力模擬),其中 是所有(在 上)的度數大於等於 的點(鏈的交會處),而 是所有(在 上)的度數等於 的點。鏈的個數顯然是個的。注意到 (因為每次分岔至少會多出一個葉子),因此每次暴力複雜度是
。
又因為每次戳完,有水的點會減少個(只有被戳的那個點即使是葉子也有可能留著)。因此均攤下來這樣是的。
一開始有沒水的點的處理方式與 Subtask 2 相同。
如果現在戳了沒水的點,有水的點只會至多多一個(的鄰居裡面離該點最近的點),因此以上複雜度估計還是好的。至於要找到最近的點的方法可以用 倍增法或樹壓平之類的。官解用的是 LCT。
這題根本暴力模擬題,唯一的難度就只有維護那個大便結構。出題者寫了三個小時的官解,加上中間受不了跑去休息的三個小時,以及寫完以後除了四個小時的蟲,總共花了十個小時。負責驗題的大概斷斷續續奮鬥了兩三天最後放棄了QQ