Codeforces Round 969 (Div. 1) 記錄
rating:\(\textcolor{purple}{1928} \rightarrow \textcolor{purple}{2005}\)。
場切了 ABC,2:23 過的 C pretest,DEF 都沒開到(
A
簡單博弈題。\(\texttt{Clist *} \color{blue}{1743}\)。
對於除了首尾以外的 \(0/1\) 連續段,都會提供恰好一個 \(01\) 和恰好一個 \(10\)。
如果開頭是 \(1\) 則不會提供 \(01\) ,結尾是 \(1\) 則不會提供 \(10\),這兩個又可以抵消掉,\(0\) 同理。
因此得到,一個葉子會提供 \(1\) 的得分,當且僅當這個葉子的權值和根的權值不同。
那可以做簡單分討。設葉子節點上的問號數量是 \(x\),非葉子上的問號數量是 \(y\)。
如果根節點上不是問號,那麼 Alice 能得到的答案增量是 \(\lfloor(x + 1) / 2\rfloor\)。
如果跟節點上的值是問號,當葉子節點上的 \(1\) 的個數和 \(0\) 的個數不相等時,Alice 可以先手令根節點的權值是葉子節點上 \(1\) 的數量和 \(0\) 的數量較少的那個數,並獲得 \(\lfloor x / 2\rfloor\) 的增量。
否則,誰拿到根誰吃虧,可以透過判斷 \(y\) 的奇偶性簡單判斷 Alice 取 \(\lfloor (x + 1) / 2\rfloor\) 還是 \(\lfloor x / 2\rfloor\)。
B
\(\texttt{Clist *} \color{purple}{2033}\)。
答案單調下降,因此考慮離線後時光倒流計算增量。
首先考慮在什麼情況下取到一條路徑上的最大答案。
時光倒流後,相當於一開始給定一棵樹,我們稱每次操作是選定一條邊制約解除。
那麼設當前所有被制約解除的邊的邊權和為 \(v\),那麼對於一條路徑經過的邊,有一部分被制約解除了,一部分沒有,設沒有被制約解除的邊的邊權和為 \(u\)。假設這條路徑上存在一條邊被制約解除,那麼這條路徑的邊權就是 \(u + v\),否則權值為 \(u\)。
考慮題目中路徑的性質。樹是按 dfs 序編號的,那麼每條邊會被兩條 \(i \rightarrow (i \bmod n + 1)\) 的路徑經過。對於點 \(i\),設 \(i\) 的子樹內的編號範圍為 \([i, r_i]\),那麼每次解除 \(i\) 到 \(i\) 父親的這條邊,影響到的只有 \((i - 1) \rightarrow i\) 的路徑和 \(r_i \rightarrow (r_i \bmod n + 1)\) 的路徑。
那麼問題就變得很簡單了。首先算出所有邊權都確定時的答案,並記一個 \(cnt\) 描述當前存在被制約解除的邊的路徑的條數和一個 bool 陣列描述每一條路徑中是否存在被制約解除的邊。
對於每次操作,設當前的邊的權值為 \(val\)。首先當前的邊先消除影響,將答案減去 \(2val\),然後把 \(val\) 加到 \(v\) 中。
因為每次只會修改兩條路徑,所以可以直接修改 bool 陣列並維護 \(cnt\),然後再讓答案增加 \(cnt \cdot v\) 即可。
C
\(\texttt{Clist *} \color{orange}{2307}\)。
喜歡我猜結論題嗎?
首先每次拿到一個陣列,顯然將它一直操作直至無法操作為止後如果連續就不合法。
考慮無法操作的集合是什麼樣子的。假設集合內有兩個數的差為偶數那麼一定操作。而無法操作即無論選擇哪兩個數操作,其能產生出的數都已經在集合中了。
然後手玩下發現,不能操作當且僅當這段陣列從小到大排序後,差分陣列的 \(\gcd\) 不是 \(2\) 的整數次冪或 \(0\)。
胡個證明。首先如果排序後兩個相鄰數作差後是偶數,那麼顯然將它一直操作下去。最後可以得到一個任意相鄰數的差都為奇數的陣列。
那麼假設場上出現的間隔的種類數超過 \(1\) 種,那麼一定有一組 \((i, i + 1, i + 2)\) 滿足 \((a_{i + 1} - a_i) \not = (a_{i + 2} - a_{i + 1})\)。此時 \((i, i + 2)\) 必然可操作,並且操作後出現的數一定沒有出現過。那麼一直執行上述操作,最後就能得到一個所有數相等的陣列,並且這個相等的值顯然是所有差分的 \(\gcd\) 不斷除以 \(2\) 的結果。而如果最後所有差都是 \(1\) 那就達到目的了,推回去就是 \(\gcd\) 是 \(2\) 的整數次冪就是合法的。
問題變成了,問有多少個子段排序後的差分的 \(\gcd\) 是 \(0\) 或 \(2\) 的整數次冪。
然後胡個結論,排序後的差分的 \(\gcd\) 等於不排序時差分的絕對值的 \(\gcd\)。
證明它。根據 \(\gcd\) 的性質有 \(\gcd(a, b) = \gcd (a + b, b)\),所以我們可以把差分給字首和回去 \(\gcd\) 不變,然後發現字首和後的陣列時原陣列每個數都減去最小值的結果。然後我們任意調換原陣列的順序後,原陣列每個數都減去最小值的 \(\gcd\) 是不變的。而排序後的 \(\gcd\) 恆為正,所以很自然的每個數差分後取絕對值的 \(\gcd\) 是不變的。
那就直接把差分處理出來得到一個長度為 \(n - 1\) 的陣列,問題變成了有多少個子段的 \(\gcd\) 為 \(0\) 或 \(2\) 的整數次冪。問題變成了 ARC023D] GCD區間,簡單 st 表後二分並開 map 存起來即可,當然這題因為詢問數量極小肯定有更快的做法(sol:st 表後雙指標或直接不帶刪雙指標)。但是賽時一看轉化成這題就懶得繼續思考了。
開學了,還沒開始停課,補題速度變慢了(悲