用來解決一類與位運算有關卷積問題:
\[ c_i = \sum_a_j * b_k \] 2
基礎思想和fft類似,我們正變換求出乙個類似點值表示的東西,然後用它直接乘,然後逆變換。
fft我們對下標奇偶分治。這裡求變換我們按位分治。
與和或根據位運算的性質很好想,可以自己推一推異或記住就行了
二進位制運算的性質很強啊,重點在於沒有進製!所以說類似快速冪可以直接對「點值表示」做.
\[ a=(a_0,a_1) \\ fwt(a) = (fwt(a_0)+fwt(a_1),\ fwt(a_1)) \\ ifwt(a) = (ifwt(a_0)-ifwt(a_1),\ ifwt(a_1)) \\ \]
\[ a=(a_0,a_1) \\ fwt(a) = (fwt(a_0),\ fwt(a_1) + fwt(a_0)) \\ ifwt(a) = (ifwt(a_0),\ ifwt(a_1)- ifwt(a_0)) \\ \]
\[ a=(a_0,a_1) \\ fwt(a) = (fwt(a_0)+fwt(a_1),\ fwt(a_0)-fwt(a_1)) \\ ifwt(a) = (ifwt(\frac),\ ifwt(\frac)) \\ \]
**:4589: hard nim
#include #include #include #include #include using namespace std;typedef long long ll;
const int n = (1<<17)+5, p = 1e9+7, inv2 = (p+1)/2;
bool notp[n]; int p[n/10];
void sieve(int n)
}}void fwt(int *a, int n, int flag)
int n, m, a[n];
int main() {
freopen("in", "r", stdin);
sieve(n-1);
while(scanf("%d %d", &n,&m) != eof) {
memset(a, 0, sizeof(a));
for(int i=1; i<=p[0] && p[i]<=m; i++) a[p[i]] = 1;
int len = 1; while(len <= m) len<<=1;
fwt(a, len, 1);
for(int i=0; i
快速沃爾什變換
用於解決集合邏輯運算的演算法。就是能夠造出類似多項式卷積的形式 可以是 證明解釋什麼的。找了大半天了,也沒找到個自己能看懂的,好吧,背模板 題面 給出n個小於2 20的數,指定 其中之一為操作opt,求給定的n個數中任選兩個,經過opt操作後能得到的最大值是多少?solution 記fi 數字i出現...
學習筆記 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
目錄2.按位與卷積 3.按位異或卷積 4.高維前 字尾和與各類卷積的聯絡 5.題目小結 想要快速計算 c k a textb k sum j k a ib j 我們可以利用 mathtt 的思想 將係數多項式轉化成點值多項式,mathcal o n 求得答案後將其還原成係數多項式。假設 a,b 均為...