ARC180 部分簡要題解

Achtoria發表於2024-07-31

C

\(f_{i, j}\) 為考慮前 \(i\) 個數,當前選出來的子序列和為 \(j\) 且強制最後一個選出來的數不為 \(j\) 的方案;設 \(g_{i, j}\) 為考慮前 \(i\) 個數,當前選出來的子序列和為 \(j\) 且強制最後一個選出來的數必為 \(j\) 的方案。注意到一個合法方案可以唯一與一個最後一個選出來的數會變的方案對應(不斷刪掉最後一個選出來但沒變的數,結果不變,注意這裡包括全部都不選),於是有轉移:

\[f_{i, j} = f_{i - 1, j}(j = a_i) \\ f_{i, j} = f_{i - 1, j} + f_{i - 1, j - a_i} + g_{i - 1, j - a_i}(j \ne a_i) \\ g_{i, j} = g_{i - 1, j}(j \ne a_i) \\ g_{i, j} = f_{i - 1, 0}(j = a_i) \]

E

非常漂亮的一道題。首先反過來考慮,求出使用不超過 \(c\) 的代價能得到的最大分數。

不妨先考慮 \(c = 0\),相當於要滿足 \(n\) 條關於每個位置上逆序對的條件。考慮 \(\rm dp\),令 \(f_{i, j}\) 為近考慮排列前 \(i\) 個元素的相對順序,以相對大小第 \(j\) 小的元素作為結尾的最長上升字序列長度,轉移考慮第 \(i\) 個位置的排名,排列插入式轉移。

\[f_{i, j} = \max \begin{cases} f_{i - 1, j - 1} \\ f_{i - 1, j} (i - j - 1 \ge a_i) \\ \max\limits_{k < j} f_{i - 1, k} + 1 (i - j \ge a_i) \end{cases} \]

注意到去掉 \(f_{i - 1, j}\) 對應方案的最後一個元素,一定是 \(f_{i - 1, k}(k < j)\) 的一個方案,於是轉移二包含於轉移三。

為了方便轉移三,修改 \(\rm dp\) 定義:令 \(f_{i, j}\) 為近考慮排列前 \(i\) 個元素的相對順序,以相對大小 不大於\(j\) 小的元素作為結尾的最長上升字序列長度。於是轉移可以修改為:

\[f_{i, j} = \max(f_{i - 1, j - 1} + [i - j \ge a_i], f_{i, j - 1}) \]

為了方便令 \(j' = i - j + 1\) 於是:\(f_{i, j'} = \max(f_{i - 1, j'} + [j' \ge a_i + 1], f_{i, j' + 1})\).

由於 \(f_{i, j' + 1} \le f_{i, j'} \le f_{i, j' + 1} + 1\),於是我們可以考慮 \(f_{i, j'} = f_{i, j' + 1} + 1\) 的斷點 \(j’\)。於是轉移可以看作是新增斷點 \(i\),然後刪除 \(\le a_i\) 的最大斷點。最終答案為斷點的個數。

再考慮 \(c \ne 0\) 的情況,這等價於去掉任意 \(c\) 個限制(將對應 \(a_i \leftarrow 0\))之後的相同問題,於是我們來分析上述加刪斷點的過程。

首先,由於 \(a_i < i\),可以一開始將所有斷點 \(\{1, 2, \cdots, n\}\) 新增好,然後按順序進行刪除。

按照 \(a_i\) 從大到小考慮每次刪除,設最大和嚴格次大的 \(a_i\) 分別為 \(v_1, v_2\),所有刪除 \(v_1 \le i < v_2\) 斷點的行為均可提到最前完成,不影響結果。而接下來從 \(v_2\) 開始刪除的斷點,\(a_i = v_1\) 的那些位置就完全等同於 \(a_{i'} = v_2\) 的那些位置,遞迴進行上述操作。於是原本按順序的刪除轉化為了上面固定的從大到小的刪除,於是原問題 \(a_i\) 給出的順序就並不重要了。

再考慮將哪些 \(a_i \leftarrow 0\) 能使斷點更多:對 \(a_i > a_j\),分別考慮兩種方案,一種 \(a_i \leftarrow 0\) 一種 \(a_j \leftarrow 0\);前者將 \(a_j\) 這個刪除放到最後,後者將 \(a_i\) 這個刪除放到最後;輪到最後一次刪除時前者能刪的後者一定也能刪,故前者不劣。於是一定是選擇最大的 \(c\)\(a_i \leftarrow 0\)

由於刪除的順序不重要,於是可以按照從小到大的順序依次刪,這樣就可以求出所有去掉最大 \(c\)\(a_i\) 的結果了,這個過程可以直接線性維護。

F

原代價等價於將連乘拆開,\(\forall i\) 選一個 \(x_j ^ A(i < j \le n + 1, x_{n + 1} = 1)\) 乘起來相加。如果 \(i\) 選擇了 \(x_j ^ A\),從 \(i \to j\) 連邊構成一顆有根樹。

原問題變成隨機 \(n\)\([0, 1]\) 中的實數,排序後,對所有合法有根樹求所有 \(i \to j\) 這些邊 \(x_j ^ A\) 的乘積的和。不妨將順序倒過來,先確定排序後合法的樹結構,再考慮符合樹結構的方案。

列舉根節點下子樹的集合劃分 \(S_1, S_2, \cdots, S_m\),為了使規模減小,列舉這些子樹根的權值分別為 \(x_{r_1}, x_{r_2}, \cdots, x_{r_m}\)

問題轉化為了限制隨機上界不一定為 \(1\) 的子問題,但這樣並不方便直接求。

再轉化一下原問題,將權值修改為 \(\prod\limits_{i = 1} ^ n \left(y ^ A + \sum\limits_{j = i + 1} x_j ^ A\right)(x_1 \le x_2 \le \cdots \le x_n \le y)\) 這樣的齊次式,接下來的計算就會方便很多。

因為原問題可以轉化成欽定生成的隨機數遞增,根據對稱性答案為:

\[\begin{aligned} a_n(y) &= n!\int_0 ^ y \int_{x_1} ^ y \cdots \int_{x_{n - 1}} ^ y \prod\limits_{i = 1} ^ n \left(y ^ A + \sum\limits_{j = i + 1} x_j ^ A\right) \mathrm{d} x_1 \mathrm{d} x_2 \cdots \mathrm{d} x_n \\ &= n!y ^ {n(A + 1)}\int_0 ^ y \int_{x_1} ^ y \cdots \int_{x_{n - 1}} ^ y \prod\limits_{i = 1} ^ n \left(1 + \sum\limits_{j = i + 1} \left(\frac{x_j}{y}\right) ^ A\right) \mathrm{d} \left(\frac{x_1}{y}\right) \mathrm{d} \left(\frac{x_2}{y}\right) \cdots \mathrm{d} \left(\frac{x_n}{y}\right) \\ &= n!y ^ {n(A + 1)}\int_0 ^ 1 \int_{x_1} ^ 1 \cdots \int_{x_{n - 1}} ^ 1 \prod\limits_{i = 1} ^ n \left(y ^ A + \sum\limits_{j = i + 1} x_j ^ A\right) \mathrm{d} x_1 \mathrm{d} x_2 \cdots \mathrm{d} x_n = a_n(1)y ^ {n(A + 1)} \\ \end{aligned} \]

是關於 \(y\) 的單項式!再回到遞迴求解的部分,為了方便集合劃分的列舉,考慮 \(\rm EGF\) 新增集合大小佔位符 \(x\),令 \(f(x, y) = \sum\limits_n \frac{a_n(y)}{n!}x^n\)

對每個集合內部需要先欽定根,然後列舉根隨機的實數,故集合內部的 \(\rm EGF\) 為:

\[y ^ A\sum\limits_n \frac{(n + 1)\int_0 ^ y a_n(t) \mathrm{d}t}{(n + 1)!}x ^ {n + 1} = xy ^ A\int_0 ^ y f(x, t) \mathrm{d}t \]

\(\exp\) 組合意義,\(f(x, y) = \exp\left(xy ^ A\int_0 ^ y f(x, t) \mathrm{d}t\right)\),故:

\[f(x, y) = \exp\left(xy ^ A \int_0 ^ y \sum\limits_n \frac{a_n(1)t ^ {n(A + 1)}}{n!}x ^ n \mathrm{d}t \right) = \exp\left(\sum\limits_n \frac{a_n(1)}{n!(n(A + 1) + 1)}x ^ {n + 1}y ^ {(n + 1)(A + 1)} \right) \]

注意到 \(f(x, y) = \sum\limits_n \frac{a_n(1)}{n!}(xy ^ {A + 1}) ^ n\),令 \(z = xy ^ {A + 1}, b_n = \frac{a_n(1)}{n!}\),由上式,令:

\[g(z) = \sum\limits_n b_nz ^ n = f(x, y) = \exp\left(\sum\limits_n \frac{b_n}{n(A + 1) + 1}z ^ {n + 1} \right) \]

兩邊求導得遞推式:

\[\begin{aligned} & g'(z) = \sum\limits_n (n + 1)b_{n + 1}z ^ n = \left(\sum\limits_n b_nz ^ n\right)\left(\sum\limits_n \frac{(n + 1)b_n}{n(A + 1) + 1}z ^ n\right) \\ &\Rightarrow b_{n + 1} = \frac{1}{n + 1}\sum\limits_i ^ n \frac{(i + 1)b_ib_{n - i}}{i(A + 1) + 1} \end{aligned} \]

直接暴力即可,複雜度 \(\mathcal{O}(n ^ 2)\),也可以用半線上卷積最佳化到 \(\mathcal{O}(n \log ^ 2 n)\)

相關文章