SDOI2017 切樹遊戲

2022-08-15 15:30:12 字數 1646 閱讀 9659

設 \(f_\) 表示 \(x\) 子樹中,所有包含 \(x\) 且異或和為 \(i\) 的連通塊數量,\(f_\) 表示 \(x\) 子樹中異或和為 \(i\) 的連通塊數量。顯然,有公式

\[f_=f_+\sum\limits__x}f_

\]現在考慮 \(f_\) 的轉移。假如我們要合併 \(x\) 與某個兒子 \(y\) 的dp陣列,則顯然有公式

\[f_=\sum\limits_k=i}f'_\times(f_+[k=0])

\]其中 \(f'\) 是老的 \(f\) 陣列。

發現這是異或卷積形式,可以fwt優化。

但是我們發現,因為dp過程中全程要麼在卷積,要麼在做加法,對fwt後的陣列作也是一樣的。因此我們重新修改定義,將 \(f\) 陣列全數修改為fwt後的陣列。又因為 \(z^0\) 這個函式在fwt後會得到 \(\sum\limits_^mz^i\),因此轉移式變更為

\[f_=f_+\sum\limits__x}f_

\]\[f_=f'_\times(f_+1)

\]直接硬dp,單次複雜度 \(o(nm)\)。

現在考慮輕重鏈剖分。設 \(g\) 表示僅考慮輕兒子時的答案。若只考慮 \(x\) 的乙個重兒子 \(y\),則有

\[f_=g_\times(f_+1)=g_f_+g_

\]\[f_=f_+g_+f_=g_f_+g_+g_+f_

\]當然,這裡的所有東西都是函式,連上面的 \(1\) 都不例外,指的是元素全為 \(1\) 的函式。

同時,要留心一點常規 \(g\) 的轉移:

\[g_=\text(z^)\prod\limits__x}(f_+1)

\]\[g_=\sum\limits__x}f_

\]需要注意的是,葉節點的 \(g\) 陣列應直接是其 \(f\) 陣列,故對於葉子節點,有 \(g_=g_=\text(z^)\)。

我們可以列出轉移矩陣來:

\[\beginf_\\f_\\1\end\beging_&g_&0\\0&1&0\\g_&g_+g_&1\end=\beginf_\\f_\\1\end

\]\(3\times3\) 矩陣就有著 \(3^3\) 的常數,不好玩。但是,當我們計算兩個上述矩陣的積後

\[\begina_1&b_1&0\\0&1&0\\c_1&d_1&1\end\begina_2&b_2&0\\0&1&0\\c_2&d_2&1\end=\begina_1a_2&b_1+a_1b_2&0\\0&1&0\\a_2c_1+c_2&b_2c_1+d_1+d_2&1\end

\]發現矩陣的積不會影響其餘位置的取值。

因此我們考慮只維護 \(a,b,c,d\) 四個位置的值,即可壓縮矩陣為 \(2\times2\)。

於是現在的轉移矩陣就壓縮為

\[\begina_1&b_1\\c_1&d_1\end\begina_2&b_2\\c_2&d_2\end=\begina_1a_2&b_1+a_1b_2\\a_2c_1+c_2&b_2c_1+d_1+d_2\end

\]同時,其存在單位元

\[\begin1&0\\0&0\end

\]我們同時還要支援從鏈頂父親的 \(g\) 陣列中刪掉乙個 \(f\) 陣列的操作。這樣就需要支援除法。但是你不能保證fwt不會出現零。但我們可以維護每個位置的非零數之積是什麼,再維護每個位置出現了多少零,這樣分開處理,即可支援除法。

**先咕著

SDOI2017 切樹遊戲

題目 二輪毒瘤題啊 辣雞洛谷竟然有卡樹剖的資料 還是 loj 可愛 首先這道題沒有帶修,設 dp 表示以 i 為最高點的連通塊有多少個異或和為 j g sum dp k in tree i 表示 k 在 i 子樹內部 我們可以直接把每乙個權值 fwt 一下,大力合併就好了,合併直接對位相乘,只需要在...

SDOI2017 切樹遊戲

一棵樹,每個點有點權,多次操作 1.單點修改乙個點的點權 2.詢問有多少棵子樹點權異或和為 k n leq 30000,k leq 128,q leq 30000 sol 動態 dp 為防止自己忘,再寫一遍 乙個點的 dp 值 sum dp dp 這樣就可以一條重鏈一起轉移 用線段樹維護重鏈上的轉移...

SDOI2017 硬幣遊戲

考慮生成函式來做 g x 函式就是0 0 x 1 x s n s x n 就是最後s位必須填這個串,但是前面隨便填的方案數 然後列舉之前出現了哪個串 包括自己 如果沒有相交,就是fj x g x 還有就是有前字尾有相交部分,pji x 中的第k位,表示i的長度為m k的字首和j的長度為m k的字尾是...