2021 ICPC Southeastern Europe Regional Contest

A

比較字符串的字典序可以進行貪心,所以用一個指針從前往後掃描,維護一個計數器,對於當前字符,如果兩個串相同則可以累加計數器,否則若字典序較小,則統計答案,合法的區間左端點個數爲計數器累加的數,右端點個數爲右邊剩下的數,若字典序較大,則清空計數器,因爲以後的都不滿足題意。

B

不難發現加的操作可以直接使用可持久化線段樹維護,對於區間覆蓋來說不太好弄,因爲區間覆蓋後無法很好的維護列,考慮列實際上很少,以及可持久化線段樹具有很好的合併功能,所以對於每種可能的合併情況都使用線段樹進行維護,如果區間覆蓋就直接在沒有這一列的情況下加入即可。

C

容易想到一個看上去時間複雜度很假的做法,枚舉顏色,然後做樹上揹包,實際上用到一個結論,在樹上歸併時,如果限制子樹大小爲 \(k\),那麼最終的時間複雜度是 \(O(nk)\),這樣的話最後時間複雜度爲 \(O(n^2)\)

下面證明這個結論,有兩種方法理解。

方法一,考慮將兩個聯通塊歸併時,這兩個連通塊的大小,第一種,都大於 \(k\),那麼歸併一次的時間複雜度是 \(O(k^2)\),歸併次數不超過 \(O(\frac{n}{k})\),第二種,僅有一個大於 \(k\),那麼每歸併一次就會少一個小於 \(k\) 的連通塊,這樣也是 \(nk\),第三種,都小於 \(k\),這樣可以先合併出若干個大於 \(k\) 的聯通塊,每個連通塊消耗 \(k^2\) ,最多 \(\frac{n}{k}\) 個塊。

方法二,歸併時強行假設枚舉的點對是 dfn 序最接近的 \(2k\) 個點,這樣點對中兩個點的 dfn 序差不超過 \(2k\),最後得到的點對是 \(nk\) 級別的。

E

首先 \(B\) 數組的順序是不影響最終結果的,於是先將 \(B\) 數組排序方便處理,不難發現我只需要知道前一個數是多少就能夠對當前數進行決策,而前一個數最多隻有 \(m+1\) 種情況,得到一個 \(N^2\) 的算法,定義 \(dp[i][j]\) 表示當前考慮到第 \(i\) 個位置,這個位置上放 \(b_j\) 的最小步數,若 \(j\)\(0\),則表示不替換,轉移只有如下幾種情況,當 \(a_i>a_{i-1}\) 時,\(dp[i][0]=min(dp[i][0],dp[i-1][0])\),當 $a_i<a_{i-1} $時,對於所有滿足 \(b_j>a_{i-1}\)\(dp[i][j]=min(dp[i][j],dp[i-1][0]+1)\),對於所有情況,\(dp[i][0]\) 和所有比它小的 \(b_j\)\(dp[i-1][j]\) 的最小值,對於 \(dp[i][j]\) 的更新,採用貪心策略,\(dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1)\),這樣做是因爲如果當前放 \(b_j\) ,那麼前面放 \(b_{j-1}\) 一定不劣,這樣做是 \(N^2\) 的,考慮優化,發現可以將不替換的單獨拿出來考慮,這個時間複雜度可以接受,只需要考慮替換時怎麼維護 \(dp\) 值,發現需要做的只有將整個數組平移一個單位和區間對一個數取 \(min\) ,使用吉司機線段樹維護即可。

F

不難發現如果要使用毒藥,那麼一定是在最開始用了若干瓶,然後又去抵消了一個前綴的回覆效果,只需要枚舉這個前綴是多少然後計算最優情況即可。

G

因爲 \(w\) 和最終答案的和都是求最大值,所以可以直接去掉絕對值,這樣相當於給 \(n\) 個數負號,\(n\) 個數正號,使得和最大,顯然,負號會給到數對中的較小值,正號會給到數對中的較大值,考慮什麼時候給正號比給負號優,設第一對給了正號,第二對給了負號,那麼給第二對正號更優當且僅當 \(a_1-b_2<a_2-b_1\),發現按照 \(a+b\) 排序然後取前 \(n\) 個即可。

J

根據 \(A,B,C\) 的數量,我們可以求出 \(AB,BC,AC\) 各自有多少個,以 \(AB\) 爲例,它有 \(\frac{cnt_A+cnt_B-cnt_C}{2}\) 個,由於 \(B\) 的前面也能接,後面也能接,所以我們優先處理 \(B\),如果存在劃分方案,那麼將 \(B\) 的前 \(cnt_{BC}\) 個和 \(C\) 配對,\(B\) 的後 \(cnt_{AB}\) 個和 \(A\) 配對,這樣一定是不劣的,考慮 \(AB\) 中用到的 \(A\) ,應該是距離 \(B\) 最近的 \(A\)\(BC\) 同理,這樣剩下的 \(AC\) 一定可以配對,否則不存在劃分方案。

K

如果根確定,那這題十分顯然,只需要根據葉子節點的大小去搜索即可。

現在問題轉化爲如何確定根,考慮對於一個結點來說,它要麼作爲根,要麼有一個父親,考慮與這個點相鄰的若干塊中,影響這個點的只有最小的葉子最大的那個塊,比較這個葉子和當前點誰放在序列上更優即可。

具體實現可以從最小的葉子結點開始往上找根,然後依次更新答案。

L

實際上最多隻要兩次即可實現,只需要找到一個前綴,讓它恰好包含一種字符出現了 \(n\) 次,將後面區間分成兩段分別覆蓋一種字符即可,於是依次判斷能否用 \(0,1\) 次來實現這個問題,\(0\) 次直接判斷,\(1\) 次用雙指針即可。

N

考慮對 \(a\) 數組操作不太好弄,因爲不一定每一個 \(a_i\) 都會向下產生貢獻,而 \(b_i\) 則不是,如果存在 \(b_i\),那麼它一定是需要被抵消的,所以每次將 \(b\) 數組往上推即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章