1. 程式人生 > 其它 >NOI 2021 部分題目題解

NOI 2021 部分題目題解

最近幾天覆盤了一下NOI 2021,愈發發覺自己的愚蠢,可惜D2T3仍是不會,於是只寫前面的題解

Day1 T1

可以發現,每次相當於將 \(x\to y\) 染上一種全新顏色,然後一條邊是重邊當且僅當兩端有顏色且相同,於是就可以使用樹鏈剖分維護了。

複雜度 \(\Theta(n\log^2n)\)

Day1 T2

可以發現,當 \(n_i\) 都相同的是,答案就是鄰接矩陣行列式的積,也即是鄰接矩陣積的行列式。

拓展發現,\(n_i\) 不同的時候依舊適用,不過不會證明。

Day1 T3

首先可以發現,在縮點之後一定存在一種樹形結構使得不改變連通性,因為假設存在 \(z\to x,y\to x,z\to y\)

,那麼 \(z\to x\) 是不需要的。所以在構造樹的時候可以選一個入度為 \(0\) 的點開始,然後每次兒子從 scc 序大的開始。

假設已經建好了樹,可以發現 \(k=0\) 時有解的話就是 \(x\to y\) 上鍊上點的大小之和,\(k=1\) 的話需要分類討論,\(k\) 更大時顯然分類討論不是很好搞。

發現假設我們定義“好點”為新增邊的端點中既能從 \(s\) 到達又能到 \(t\) 的點(合法情況下包括 \(s,t\)),那麼一個點合法當且僅當祖先中有“好點”,子樹中有“好點”。

那我們就可以建出虛樹,然後算貢獻了。(然而似乎可以不用建出虛樹)。

Day2 T1

不難發現分成 \(16\)

段的話,如果有解那麼解的方案一定有一段完全相同,然後你發現隨機情況下一段最多有 \(7\) 個左右,暴力判就好了。算差異的話可以用 __builtin_popcount \(\Theta(1)\) 計算。

Day 2 T2

首先可以看出並不需要除以 \(\gcd\)

可以發現如果 \(a_i\) 是確定的,那麼:

\[\begin{bmatrix} a_i & 1\\ 1 & 0 \end{bmatrix}\]

從右往左算的積的 \((0,0)\) 位和 \((0,1)\) 位就是答案。

考慮 W 操作的影響,你發現:

\[\begin{bmatrix} 1 & 1\\ 0 & 1\\ \end{bmatrix} \times \begin{bmatrix} a_i & 1\\ 1 & 0 \end{bmatrix} = \begin{bmatrix} a_i+1 & 1\\ 1 & 0 \end{bmatrix} \]

所以就相當於在後面增加一個

\[\begin{bmatrix} 1 & 1\\ 0 & 1 \end{bmatrix} \]

的矩陣。

考慮 E 操作,不難發現兩種情況其實操作下來等價,所以我們只需要考慮第二種情況。實際上就是增加:

\[\begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix} \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix} \begin{bmatrix} 1 & -1\\ 0 & 1 \end{bmatrix} \]

又因為矩陣有結合律,所以就相當於增加:

\[\begin{bmatrix} 2 & -1\\ 1 & 0 \end{bmatrix} \]

所以用平衡樹維護就好了。需要卡常的話可以把矩陣乘法那裡手寫而非迴圈形式。