1. 程式人生 > 其它 >【題解】AtCoder Beginner Contest 247 補題記錄

【題解】AtCoder Beginner Contest 247 補題記錄

AtCoder Beginner Contest 247

A Move Right

題意

給出一個長度為 \(4\) 且由 01 組成的序列。現在將除最後一位外每個位置上的字元右移一位。求最終得到的序列(第一位視作 0)。

思路

模擬。

B Unique Nicknames

題意

\(n\) 個人,每個人有其名 \(s_i\) 和姓 \(t_i\)。嘗試給每個人起一個暱稱 \(a_i\),使得 \(\forall 1 \leq j \leq n\)\(i \neq j\)\(a_i \neq s_j\)\(a_i \neq t_j\)。問是否存在合法方案。

\(2 \leq n \leq 100\)

思路

模擬。

map 記錄每個人的姓和名在所有姓名裡的出現次數。顯然當一個人的姓和名出現次數均大於 \(2\) 時無解。注意特判一個人的姓名相同的情況。

C 1 2 1 3 1 2 1

題意

按以下方式定義序列 \(S_n\)

  • \(S_1 = 1\)

  • \(S_n = S_{n - 1}, n, S_{n - 1}, n \geq 2\)

給定 \(n\),輸出 \(S_n\)

\(1 \leq n \leq 16\)

思路

\(n \leq 16\),暴力遞迴模擬即可。

D Cylinder

給定 \(Q\) 個操作,對於序列 \(S\),每次操作可以:

\(1\)\(S\)

末尾加入 \(c\)\(x\)

\(2\) 取出 \(S\) 開頭的 \(c\) 個元素,求它們的和。

資料保證對於操作 \(2\),當時序列中的元素總數大於等於 \(c\)

\(1 \leq Q \leq 2 \times 10^5\)

\(0 \leq x \leq 10^9\)

\(1 \leq c \leq 10^9\)

思路

樹狀陣列 + 二分。

考慮將每個操作 \(1\) 視作一個元素,維護由這些元素組成的序列:

用兩個樹狀陣列分別維護序列中 \(c\) 的字首和 \(tot\)\(c \times x\) 的字首和 \(sum\),同時用兩個指標 \(s, t\) 表示當前 \(S\)

\([s, t]\) 中的元素組成。

對於操作 \(1\),直接更改樹狀陣列和指標。

對於操作 \(2\),考慮在 \([s, t]\) 中二分出第一個位置 \(l\),使得 \(\sum\limits_{i = s}^l c_i \geq c\)。此時分類討論:

  • \(\sum\limits_{i = s}^l c_i = c\),直接樹狀陣列求和。然後 \(s = l + 1\)

  • \(\sum\limits_{i = s}^l c_i > c\),此時前 \(c\) 個元素和為 \(\sum\limits_{i = s}^{l - 1} c_i \times x_i + (c - \sum\limits_{i = s}^{l - 1} c_i) \cdot x_l\)。此時 \(c_l \leftarrow c_l - (c - \sum\limits_{i = s}^{l - 1} c_i)\),相應地需要修改樹狀陣列。

樹狀陣列複雜度 \(O(\log n)\),二分複雜度 \(O(\log n)\),總時間複雜度 \(O(Q \log^2 n)\)

E Max Min

題意

給定一個長度為 \(N\) 的序列 \(A\) 和兩個正整數 \(X, Y\)。試求出滿足 \(\forall L \leq i \leq R, \max(A_i) = X\)\(\min(A_i) = Y\) 的有序正整數對 \((L, R)\) 的個數。

\(1 \leq N, A_i \leq 2 \times 10^5\)

\(1 \leq Y \leq X \leq 2 \times 10^5\)

思路

ST表 + 二分。

考慮用 ST 表維護區間最值。列舉 \(L\),用四次二分得到 \([L, N]\) 中:

  • 第一個令 \(\forall L \leq i \leq l_1, \max(A_i) = X\) 的位置 \(l_1\)

  • 最後一個令 \(\forall L \leq i \leq r_1, \max(A_i) = X\) 的位置 \(r_1\)

  • 第一個令 \(\forall L \leq i \leq l_1, \min(A_i) = Y\) 的位置 \(l_2\)

  • 最後一個令 \(\forall L \leq i \leq r_2, \min(A_i) = Y\) 的位置 \(r_2\)

顯然 \([l_1, r_1]\)\([l_2, r_2]\) 的交區間中,每一個下標都可以和 \(L\) 構成一對滿足條件的有序數對,直接統計答案。

ST表預處理複雜度 \(O(n \log n)\),單次查詢最值 \(O(1)\),二分複雜度 \(O(\log n)\),總時間複雜度 \(O(n \log n)\)

注意 \(O(n \log^2 n)\) 的線段樹做法會被卡(或許是因為我常數大?)

F Cards

題意

\(n\) 張卡牌,第 \(i\) 張卡牌正面的數字為 \(P_i\),背面的數字為 \(Q_i\),其中 \(P_i, Q_i\) 均為 \(1\)\(n\) 的排列。問有多少種方式,使得 \(1\)\(n\) 中每個數字至少在一張卡牌的某一面中出現一次。

方案數對 \(998244353\) 取模。

\(1 \leq N \leq 2 \times 10^5\)

\(1 \leq P_i, Q_i \leq N\)

思路

轉化。

先考慮一個前置問題:若在 \(1\)\(n\) 中,兩個相鄰數字至少要選一個,一共有多少種方案?

考慮令 \(n\) 個數的方案總數為 \(F(n)\)。分類討論:

  • 若選 \(n\),則方案數為 \(F(n - 1)\)

  • 若不選 \(n\),則必須選 \(n - 1\),方案數為 \(F(n - 2)\)

顯然 \(F(1) = 1, F(2) = 3, F(n) = F(n - 1) + F(n - 2), n \geq 3\)

回到問題。不妨構造一個包含 \(n\) 個結點的圖,並在 \(P_i, Q_i\) 直接連邊。顯然圖中每個結點的度數都是 \(2\),因此這個圖是由若干個環組成的。現在問題被轉化成:求原圖的邊覆蓋總數。

顯然所有環都是等價的,因此考慮一個環的情況。令長度為 \(m\) 的環的邊覆蓋總數為 \(G(m)\)。將環的結點依次標號為 \(1\)\(m\),分類討論:

    1. 選擇邊 \((1, m)\)。此時將除 \((1, m)\) 外的邊依次標號為 \(1, m - 1\),顯然標號相鄰的邊至少要選擇一條。方案總數為 \(F(m - 1)\)
    1. 不選擇邊 \((1, m)\)。此時邊 \((m - 1, m)\) 和邊 \((1, 2)\) 都必須被選擇。同理,方案總數為 \(F(m - 3)\)

所以 \(G(m) = F(m - 1) + F(m - 3)\)

\(F\) 表達 \(G(m - 2), G(m - 1), G(m)\)

\[\begin{aligned} G(m - 2) &= F(m - 3) + F(m - 5) \\ G(m - 1) &= F(m - 2) + F(m - 4) \\ G(m) &= F(m - 1) + F(m - 3) \end{aligned} \]

又有

\[\begin{aligned} F(m - 1) = F(m - 2) + F(m - 3) \\ F(m - 3) = F(m - 4) + F(m - 5) \end{aligned} \]

所以 \(G(m) = G(m - 1) + G(m - 2)\)

手推可以發現 \(G(1) = 1, G(2) = 3, G(m) = G(m - 1) + G(m - 2), m \geq 3\)

最後所有環的 \(G\) 值乘積就是答案。

時間複雜度 \(O(n)\)

G Dream Team

題意

\(N\) 個人,第 \(i\) 個人來自第 \(A_i\) 所大學,擅長第 \(B_i\) 門學科,權值為 \(C_i\)。定義 Dream Team 為若干個人的組合,滿足:

  • Dream Team 中的所有人來自不同的大學

  • Dream Team 中所有人擅長的學科不同

設 Dream Team 最多有 \(k\) 個人。試對於 \(1 \leq i \leq k\),求包含 \(i\) 個人的 Dream Team 的最大權值和。

\(1 \leq N \leq 3 \times 10^4\)

\(1 \leq A_i, B_i \leq 150\)

\(1 \leq C_i \leq 10^9\)

思路

費用流。

考慮新建兩個起點 \(s1, s2\) 和匯點 \(t\),將每所大學和每個學科分別視作一個結點。

\(A_i, B_i\) 之間連線一條容量為 \(1\),費用為 \(C_i\) 的邊。

\(s2, A_i\) 之間連一條容量為 \(1\),費用為 \(0\) 的邊。

\(B_i, t\) 之間連一條容量為 \(1\),費用為 \(0\) 的邊。

列舉最大人數 \(k\)。每次在 \(s1, s2\) 之間連線一條容量為 \(1\),費用為 \(0\) 的邊,表示嘗試增加 \(1\) 個人。如果增廣的流量為 \(0\),說明此時已經得到最大人數,退出;反之,此時增廣該流量的最大費用就是加入的人的權值,求字首和即可。

顯然 \(k \leq 150\),時間複雜度是 O(能過)