目錄2. 按位與卷積
3. 按位異或卷積
4. 高維前/字尾和與各類卷積的聯絡
5. 題目小結
想要快速計算
\[c[k]=(a\textb)[k]=\sum_j=k}a_ib_j
\]我們可以利用 \(\mathtt\)
的思想:將係數多項式轉化成點值多項式,\(\mathcal o(n)\) 求得答案後將其還原成係數多項式。
假設 \(a,b\) 均為多項式,則 \(a+b,a-b,a\times b\) 都代表著對位運算。
\(\mid,\&,\oplus\) 分別表示或、與、異或。且若無特殊說明,\(i\subseteq j\) 表示在二進位制意義下 \(i\) 是 \(j\) 的子集。
定義\[\mathtt(a)[i]=\sum_a_j\\
\mathtt(\mathtt(a))=a
\]所以有
\[\begin
\big[\mathtt(a)\times \mathtt(b)\big][i]&=\sum_a_b_\\
&=\sum_a_b_
\end
\]按照定義將上面那個柿子 \(\mathtt\) 一下就是 \(a|b\) 了。
對於乙個多項式 \(a\),不妨設其長度為 \(2^n\),令 \(a_0,a_1\) 分別為前 \(2^\) 項,後 \(2^\) 項(其實也可以理解為將下標以二進位制的最高位分組),有:
\[\mathtt(a)=
\begin
\big(\mathtt(a_0),\mathtt(a_0+a_1)\big) & & n>0\\
a && n=0
\end
\]這個遞迴式可以這樣理解:最終能貢獻到前 \(2^\) 項的項的最高位一定為零,此時 \(a_1\) 這一部分一定無用,所以由 \(\mathtt(a_0)\) 組成;貢獻到後 \(2^\) 項的項的最高位可以為 \(0/1\),所以相當於沒有限制,此時貢獻到哪一位只由二進位制的後 \(n-1\) 位決定,所以 \(a_0[i]\) 和 \(a_1[i]\) 是等價的,可以對位相加。
由上文的證明,我們也可以得到 \(\mathtt(a_0+a_1)=\mathtt(a_0)+\mathtt(a_1)\).
\[\mathtt(a)=
\begin
\big(\mathtt(a_0),\mathtt(a_1-a_0)\big) & & n>0\\
a && n=0
\end
\]\(n=0\) 的情況就不再贅述,對於 \(n>0\) 的情況,我們直接將 \(\mathtt(a)\) 代入柿子:
\[\begin
\mathtt\big(\mathtt(a)\big)&=\big(\mathtt(\mathtt(a_0)),\mathtt(\mathtt(a_0+a_1)-\mathtt(a_0))\big)\\
&=\big(a_0,\mathtt(\mathtt(a_0)+\mathtt(a_1)-\mathtt(a_0)) \big)\\
&=(a_0,a_1)
\end
\]void or(int *f,int opt=1) (a)[i]=\sum_a_j\\
\mathtt(\mathtt(a))=a
\]所以有
\[\begin
\big[\mathtt(a)\times \mathtt(b)\big][i]&=\sum_a_b_\\
&=\sum_a_b_
\end
\]按照定義將上面那個柿子 \(\mathtt\) 一下就是 \(a\&b\) 了(其實計算 \(\mathtt(a\&b)\) 應該會更好理解,你會發現 \(\mathtt(a\&b)[i]\) 就是列舉 \(i\) 的超集 \(j\),再列舉 \(j_1,j_2\) 使得 \(j_1\&j_2=j\))。
\[\mathtt(a)=
\begin
\big(\mathtt(a_0+a_1),\mathtt(a_1)\big) & & n>0\\
a && n=0
\end
\]理解方式同上,就不再闡述。
\[\mathtt(a)=
\begin
\big(\mathtt(a_0-a_1),\mathtt(a_1)\big) & & n>0\\
a && n=0
\end
\]證明方式同上,就不再闡述。
void and(int *f,int opt=1) (a)[i]=\sum_a_j-\sum_a_j=\sum (-1)^\cdot a_j\\
\mathtt(\mathtt(a))=a
\]在證明 \(\mathtt(a\oplus b)=\mathtt(a)\times \mathtt(b)\) 之前,首先有結論:\((i\circledast j)\oplus (i\circledast k)=i\circledast (j\oplus k)\).
具體證明可以對 \(i,j,k\) 二進位制的每一位考慮,如果每一位都成立那麼總結論也可以推知。只證明一位的話分類討論或者打表都行 /ww.
那麼\[\begin
\big[\mathtt(a)\times \mathtt(b)\big][i]&=\left(\sum_a_j-\sum_a_j \right)\cdot\left(\sum_b_k-\sum_b_k\right)\\
&=\sum_a_jb_k-\sum_a_jb_k=\mathtt(a\oplus b)[i]
\end
\]\[\mathtt(a)=
\begin
\big(\mathtt(a_0)+\mathtt(a_1),\mathtt(a_0)-\mathtt(a_1)\big) & & n>0\\
a && n=0
\end
\]證明就是暴力推柿子:
\[\begin
\mathtt(a)[i]&=\sum_^(-1)^a_j\\
&=\sum_^-1}(-1)^a_j+\sum_}^-1}(-1)^a_j\\
&=\mathtt(a_0)[i]+\sum_^-1}(-1)^a_}\\
&=\mathtt(a_0)[i]+\mathtt(a_1)[i]
\end
\]若 \(n>0\):
\[\mathtt(a)=\left(\frac(a_0)+\mathtt(a_1)},\frac(a_0)-\mathtt(a_1)}\right)
\]需要證明 \(\mathtt(a_0+a_1)=\mathtt(a_0)+\mathtt(a_1)\),這個由 \(\mathtt(a)[i]=\sum (-1)^\cdot a_j\) 可以輕鬆得出。
接下來就與1.3. 逆變換相同,直接代入即可。
void xor(int *f,int opt=1) \cdot \prod_^n [0\le j_\le p_k]
\]可以發現,所謂的 \(\mathtt(a)[i]\) 其實就是 \(s_i\). 那麼我們將 \(s_i\) 與 \(t_i\) 相乘,看看得到了什麼:
\[s_it_i=\sum a_\cdot b_\cdot \prod_^n [0\le j_\le p_l]\cdot [0\le k_\le p_l]
\]定義 \(f(i)=(\max(0,p_1-1)\max(0,p_2-1)\dots \max(0,p_n-1))_2\). 是的,你沒有看錯,這個玩意兒就是零,我也覺得好它嗎怪。那麼
\[s_it_i-s_t_=\sum a_\cdot b_\cdot \prod_^n [\max\=p_l]
\]怎麼說呢,這個柿子可以用多重for迴圈來理解。如果只考慮 \(1\) 維字首和(二進位制只有 \(1\) 位)就可以畫乙個矩形來表示 \(s_it_i\),那麼 \(s_it_i-s_t_=s_it_i-s_t_\),其實這個差可以看作旋轉 \(180^\circ\) 的l
形圖案。
這個圖案就是我們要求的 \((a|b)[i]\) 了。所以說,高維字首和的差分就是 \(\mathtt\).
其實是一樣的,只不過是字首和變成了字尾和,\(\max\) 卷積變成了 \(\min\) 卷積。
我也只會口胡,你可以發現 \(\gcd\) 和 \(\text\) 卷積實際上是冪次上的 \(\min\) 和 \(\max\) 卷積。
例 1.
\(\text\)
考慮到 \(n\) 是很小的,可以枚舉行的翻轉狀態,定義狀態 \(i\) 得到的最小 \(1\) 個數為 \(c_i\). 設 \(a_i\) 為列狀態為 \(i\) 的列數,\(b_i\) 為 \(i\) 和 \(2^n\oplus i\) 更少的 \(1\) 的個數(列舉列的翻轉)。那麼有:\(c_i=\sum a_jb_\). 這就是乙個很板的 \(\mathtt\) 了。但一定要注意資料範圍的計算。
例 2.
\(\text\)
令 \(p(x)=[x\text\wedge x\le m ]\),那麼答案顯然是 \(p^n[0]\),定義 "乘法" 為 \(\oplus\).
這道題目其實就是將 \(\mathtt(a\oplus b)=\mathtt(a)\times \mathtt(b)\) 拓展到
\[\mathtt(a_1\oplus a_2\oplus\dots \oplus a_n)=\mathtt(a_1)\times \mathtt(a_2)\times \dots\times \mathtt(a_n)
\]類似於 \(a\oplus b=\mathtt(\mathtt(a)\times \mathtt(b))\),再乘上 \(c\) 得:
\[\begin
(a\oplus b)\oplus c&=\mathtt(\mathtt(a\oplus b)\times \mathtt(c))\\
&=\mathtt(\mathtt(a)\times \mathtt(b)\times \mathtt(c))
\end
\]結論可以歸納證明。
學習筆記 FWT 快速沃爾什變換
解決涉及子集配湊的卷積問題 就是解決一類問題 f k sum a i b j 基本思想和fft類似。首先轉化成為另乙個多項式 fwt a fwt b 使得 fwt a oplus b fwt a fwt b 這裡,是按位乘。這個是 o n 的。然後,再 ifwt 回去即可。類似於,直接過馬路不好走。...
學習筆雞 快速沃爾什變換FWT
快速解決 c i sum a j b k fwt使得我們 fwt c fwt a fwt b 其中 是點積,就是對應位置乘起來。而對於 orfwt c i fwt c i sum c j 那麼證明一下 begin c i sum c j sum sum a p b k sum a p b k sum...
FFT 快速傅利葉變換 FWT 快速沃爾什變換
實在是 美麗的數學啊 關於傅利葉變換的部落格 講的很細緻 非常易於理解 大概能明白傅利葉變換是幹嗎的了 但是還是不能明白為什麼用傅利葉變換來算多項式求和 在多項式中,dft就是係數表式轉換成點值表示的過程。我們熟知的是多項式的係數表示法,通過給定一組 來確定乙個唯一的多項式 而多項式還可以有另一種表...