A - Accelerator
設加速器序列為 \(a_1, a_2, \cdots, a_n\),那么考慮把題目里的式子展開:\(a_n+a_na_{n-1}+a_na_{n-1}a_{n-2}+\cdots + \prod_{i=1}^n a_i\)。
我們把它一項項考慮。對於第 \(k\) 項,如果枚舉過所有 \(n!\) 種情況,那就是對下標集合 \(\{1, 2, 3, \cdots, n-1, n\}\) 選出一個長為 \(k\) 的排列 \(a_{p_1}, a_{p_2}, \cdots, a_{p_n}\)。而每個 \(p\) 都有若干次貢獻,但我們最終要求期望,這個東西最終要被除掉,所有可以不考慮。
簡化一下式子,就是:
分子上的東西實際上就是 \([x^k]\prod_{i=1}^n (1+a_ix)\)。答案就是 \(\forall k\in \{1, 2, \cdots, n\}\) 求個和。分治 FFT 即可,復雜度 \(O(n\log^2 n)\)。
B - Boring Problem
真搞死我了這個題。特意學習了一下這種題目的一些解法,好像是什么套路?
像這種往后面隨機加字符,出現給定字符串集合的任意一個后停止,問期望長度的,主流做法有兩種:PGF 和 AC 自動機。但是這題有欽定前綴,PGF 很不好處理,而對於 AC 自動機而言就只要跑一遍就行了,因此我們考慮后者。
首先朴素的思想是,對 \(T_{1\sim n}\) 建立 AC 自動機。然后對每個結點構造方程,最后高斯消元,復雜度 \(O(n^3m^3)\),無法通過。考慮把方程的數量降下來。
注意到一個關鍵性質:對於 Trie 圖中每個點,連出的所有非樹邊的 Trie 樹深度都小於當前點。而且這個性質是一般圖跑了一個 DFS 生成樹所不具備的。
對 Trie 樹做樹鏈剖分(任意選擇重兒子),可以發現雖然 Trie 樹是 \(O(nm)\) 的,但由於只有 \(n\) 個串,鏈只有 \(n\) 條。將作為鏈頂的點設為關鍵點,並嘗試用這些關鍵點表出其他的點。
先寫出朴素的方程:\(E(x)= 1+\sum_{c\in \Sigma} E(\textit{next}_{x,c})\times p_c\)。我們把重兒子 \(y\) 移項(記 \(x\to y\) 對應字符為 \(c'\)),得:\(E(y)=\frac{1}{p_c}(E(x) - \sum_{c \in \Sigma, c \ne c'} E(\textit{next}_{x,c})\times p_c - 1)\)。根據上面的性質,我們自根向下表示,那么對於 \(y\) 而言,\(E(y)\) 與 \(y\) 的父親和兄弟相關。父親以及兄弟中的“根據 fail 指針補上的邊”都是深度淺於 \(y\) 的,都已被表示而可以直接疊加,其他的兄弟必然都是鏈頂可以直接代入。
現在每個點都有一個關於鏈頂的等式,我們選出 \(n\) 個葉子,利用葉子的期望等於 0 建立 \(n\) 個方程,\(O(n^3)\) 高消即可。最后帶入等式可以得到所有點的期望。
最后把 \(R\) 放 AC 自動機上跑一遍即可,注意特判葉子。復雜度 \(O(n^3+n^2mk+|R|)\)。
C - Club Assignment
從這個角度看問題:每次我們欽定一對點 \(u, v\) 不在同一個 club 里。不難發現一定是在所有關系 \((i, j)\) 二元組中找其中若干個 \(w_i\oplus w_j\) 最小的,越多越好,直到找到一個發現關系沖突了為止。之所以要找最小的,是因為如果我們跳過了一些小的,那這些小的就不得不成為答案(參考 MEX)。
再觀察,發現我們只要使這些關系構成一顆樹(最小異或生成樹)即可,原因是我們不必等到出現沖突,也不用管是不是沒有成樹就出現了沖突,答案方案就已經固定。對於一個固定的方案,我們可以通過 01-Trie 求解答案。
而求異或最小生成樹是個套路問題了。每次按某一位(從高位到低位枚舉)分治,然后借助 01-Trie 找到聯立兩個點集的最小邊即可。總復雜度 \(O(n\log^2 w)\)。
D - Artifacts
閱讀理解題。幾個實現技巧:
getline讀入整行;std::string中的find函數可以識別類別;sscanf讀取數字。
F - Fixing Networks
考慮最省頂點的方式,就是構造 \((d+1)\) 個點的完全圖,用以應付一個 department。最后只需要考慮 \(c=1\) 的情況了。
考慮如下構造:將 \(n\) 個點排成環,每個點向兩側相鄰的 \(\lfloor d/2\rfloor\) 個點連邊。如果 \(d\) 為奇數就向對面再連邊。如果 \(n\) 是奇數使得沒有對面的點,那說明無解,因為這樣整張圖的度數和就是奇數了。
注意特判 \(d=0,1\),以及點數不夠用的情況(\(c(d+1)>n\))。
G - Game on Sequence
一開始有一個比較怪的想法,就是每次 push back 后,從后往前暴力按必勝必敗態定理更新,再加一個如果對當前考慮的點不起作用就跳過。但是感覺不好操作也沒啥前途就先棄了。
其實有更優秀的解法:記 \(s_i\) 為 \(i\) 這個位置先手是否必勝。
考慮一個關鍵性質:對於出現超過一次的 \(x\),選取 \(A_i=A_j=x\) 且 \(i<j\) 的一對 \((i,j)\)。討論一下 \(s_j\):
- 如果 \(s_j = 0\),那么顯然 \(s_i = 1\);
- 如果 \(s_j = 1\),那么由於 \(j\) 可以到達的點中存在一個 \(s=0\) 的,而 \(i\) 可以到達 \(j\) 可達的所有位置,那么 \(s_i\) 仍然 \(= 0\)。
也就是說,如果詢問一個 \(k\),滿足 \(A_k\) 不是最后一次出現的,那么 \(s_k=1\)。如果是最后一次出現的,我們可以暴力維護 dp 去應付這種詢問。對一個點暴力 dp 復雜度是 \(O(\log A)\),每次 push back 要對所有 \(A\) 都做一遍(這里注意順序)。
總復雜度 \(O(nA\log A)\)。
I - Nim Cheater
根據博弈論基礎知識(SG 定理),Nim 游戲的后手必勝充要條件是,所有石子堆的石子個數異或起來的結果為 \(0\)。那轉化后的題意就是,對於每次修改操作后,選出一個總花費最大的集合,滿足集合中元素的權值異或和為 \(0\)。修改操作有添加一個元素,以及撤銷。
下面記 \(U=2^{14}=16384\)。一個顯然的 dp 是:\(f(u)\) 表示選取的異或和為 \(u\),最大花費和是多少。每當加入一個元素,就可以在 \(O(U)\) 時間內更新 \(f\)。
由於只有添加和撤銷操作,不難發現操作構成一棵樹形結構。建樹后跑 DFS,對每個點都計算一邊 dp 數組。直接這樣做是 \(O(U\times n)\) 的時空復雜度,然而空間限制只有 8 MB,無法通過。
題解提供了一個優秀的想法:由於 DFS 的順序並不影響結果,考慮輕重鏈剖分。對於每個點,我們先計算輕兒子,並將 \(f\) 數組復制;最后計算重兒子是直接繼承 \(f\) 數組。得益於一棵樹上每個點到根的路徑上都只有不超過 \(O(\log n)\) 條輕邊,那么一個點實際上只要保留 \(O(U\log n)\) 大小的祖先上的信息。
J - Jewel Grab
轉化詢問:對於一個詢問 \(s, k\),找到一個最長的區間 \([s,t]\),滿足區間中出現次數超過一次的元素的,出現次數減一,的和,不超過 \(k\)。然后對於所有區間中出現次數超過一次的元素,找出其中權值最大的求和;對其他的元素直接求和。計算最終結果。
如果“出現次數”、“區間”相關的題目做多了,不難反應到,定義一個 \(\textit{last}_i\) 表示位置 \(i\) 的元素在序列中上一次出現的位置(第一次出現則 \(\textit{last}_i = 0\))。那么上述的 \(t\) 就是最大的一個整數,滿足 \(\sum_{i=s}^t [\textit{last}_i < s] \le k\)。
抓住 \(k\le 10\),即 \(k\) 很小這個特點。考慮我們可以暴力找出所有 \(last_i<s\) 的這些 \(i\),具體的,建立線段樹,維護區間 \(\textit{last}\) 的最小值,然后一次線段樹上二分即可找到一個 \(\textit{last}_i < s\) 的最近的 \(i\)。如此往復 \(O(k\log n)\) 可以完成所有這樣位置的搜尋。
然后我們實現統計答案:求出 \([s, t]\) 的權值和,然后減掉出現次數超過一次的,但不是最大的元素的權值。這里要減去的只有 \(O(k)\) 個。
最后修改是非常簡單的事情,復雜度 \(O(mk\log n)\)。
K - Candy Ads
沒寫,口胡一下。可以說非常明顯的 2-SAT 了,將時間看做一維,三維空間下相交說明兩者二選一,以及 \(m\) 個額外限制也是 2-SAT 量身定制。
一開始想了一個比較繁瑣的線段樹優化建圖做法,然后發現四百萬乘上 \(\log\) 的時間有點卡,就不管了。
結果發現這玩意可以跑 bitset!(事實上這種很多維度的東西都可以想想這個?)考慮最終我們用 bitset 去維護整個 \(O(n^2)\) 大小的鄰接矩陣,然后用 Kosaraju 算法在上面跑。
建圖時就體現 bitset 的優越之處了。我們考慮有,兩者相交,當且僅當 \(x\) 方向相交 \(\land\) \(y\) 方向相交 \(\land\) 時間區間相交。三維的信息我們做三次(或六次)就行了。時間復雜度差不多是 \(O(n^2/w + m)\)。
為什么我不寫呢?因為這題空間只有 512 MB,所以要分塊處理,實在有點麻煩,不想寫了。
L - Random Permutation
從排列的角度考慮問題:對於一個排列 \(p\),有多少合法的 \(a\)?顯然是 \(n!\)。而所有 \(n!\) 種排列都對應 \(n!\) 種 \(a\),那么答案就是 \((n!)^2/n^n\)。
然而我傻掉了,使用找規律通過了此題。
