我們要求形如這樣的乙個卷積:
\[h_s =\sum_\sum_ [l\cup r=s] f_l g_r
\]回憶一下之前所學的莫比烏斯反演,本質上是把質因子看成多重集合,這裡的集合並等價於莫比烏斯反演的兩個數的 \(\text\),不妨直接對這個集合做莫比烏斯變換,定義:
\[f'_s = \sum_ f_t
\]\[f_s = \sum_ (-1)^ f'_t
\]對這個卷積左右兩邊都反演一下可以得到:
\[h'_s = \sum_\sum_[l \cup r \subseteq s]f_lg_r \\
h'_s = \sum_\sum_[l \subseteq s][r \subseteq s]f_lg_r \\
h'_s = \sum_[l \subseteq s]f_l\sum_[r \subseteq s]g_r \\
h'_s = f'_sg'_s
\]然後只需要 \(o(n2^n)\) 簡單遞推出 \(f'\) 就可以求解了:
我們要求形如這樣的乙個卷積:
\[h_s =\sum_\sum_ [l\cap r=s] f_l g_r
\]類似關於倍數的莫比烏斯反演,將反演的式子重新定義一下就好了:
\[f_s = \sum_ (-1)^ f'_t
\]我們要求形如這樣的乙個卷積,其中 \(\bigoplus\) 表示異或:
\[h_s =\sum_\sum_ [l\oplus r=s] f_l g_r
\]這裡先引入乙個在 vfk 《炫酷反演魔術》課件中的乙個看上去沒用的東西輔助推導:
\[\frac \sum_ (-1)^ = [s = \emptyset]
\]正確性可以自己驗證一下:
然後這裡定義 \(f\) 的沃爾什變換 \(f'\):
\[f'_s = \sum_ f_t (-1)^ \\
\]考慮怎麼求逆變換:
\[f_s = \sum_ f_t [s \oplus t=\emptyset] \\
f_s = \sum_ f_t \frac \sum_ (-1)^ \\
f_s = \frac \sum_ f_t \sum_ (-1)^(-1)^ \\
f_s = \frac \sum_(-1)^\sum_ f_t (-1)^ \\
f_s = \frac \sum_(-1)^f'_a \\
\]然後對於原來的卷積形式進行一些變換:
\[h_s = \sum_\sum_ [l\oplus r\oplus s=\emptyset]f_lg_r\\
h_s = \sum_\sum_
\frac \sum_ (-1)^f_lg_r \\
h_s = \frac \sum_\sum_
\sum_ (-1)^(-1)^(-1)^f_lg_r \\
h_s = \frac \sum_ (-1)^ \sum_(-1)^f_l\sum_
(-1)^g_r
\]根據之前推出的沃爾什變換:
\[h_s = \frac \sum_ (-1)^f'_sg'_s \\
h'_s =f'_s g'_s
\]與上面類似的,接下來只需要 \(o(n2^n)\) 遞推出 \(f'\) 即可。
我們要求形如這樣的乙個卷積:
\[h_s =\sum_ f_t g_
\]\[h_s =\sum_\sum_ [l\cup r=s][cnt_l+cnt_r=cnt_s] f_l g_r
\]對於 \(cnt\) 相同的 \(f ,g\) 放在一起做快速莫比烏斯變換,對於 \(cnt\) 相同的 \(h\) 列舉乙個 \(l\) 的大小後直接點乘即可,複雜度 \(o(n^22^n)\)
預處理出每乙個集合劃成乙個州是否可行,計算出 \(g_s\) 當州可行時為 \(sum_s^p\) 否則為 \(0\)
設 \(f_s\) 表示當前選取集合為 \(s\) 時的滿意度之和,不難得到遞推式:
\[f_s = \sum_ \frac}
\]提出乙個 \(sum_s^p\) 可以得到:
\[\frac} = \sum_ f_t g_
\]後面是乙個熟悉的子集卷積的形式,觀察到都是由 \(cnt\) 的 \(f\) 轉移到 \(cnt\) 大的 \(f\) ,對 \(g\) 求莫比烏斯變換後直接分層點乘即可。
注意點乘完處理回去的時候由一些細節,子集卷積後只有 \(cnt_s=\) 當前列舉的大小的位置答案是正確的,要把不正確的位置清 \(0\) 不然會影響後面的遞推值。
code
/*program by mangoyang*/
#include#define inf (0x7f7f7f7f)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template inline void read(t &x)
#define int ll
const int n = 25, len = 5000005, mod = 998244353;
vectorg[n];
int f[n][len], h[n][len], sum[len], dig[len], fa[n], w[n], n, m, p;
inline void up(int &x, int y)
inline int ask(int x)
inline int pow(int a, int b)
inline int check(int s)
} for(int i = 0; i < n; i++)
tot += ((s >> i) & 1) & (fa[i] == i);
return tot > 1;
}inline void fmt(int a, int sgn)
if((flag || check(s)) && dig[s] != 1)
h[dig[s]][s] = pow(sum[s], p);
} for(int i = 0; i <= n; i++) fmt(h[i], 1);
f[0][0] = 1, fmt(f[0], 1);
for(int i = 1; i <= n; i++)
cout << (f[n][(1
}
集合冪級數感性學習筆記
集合冪級數的性質真的太美了。這裡簡要記錄一些操作。下文若無特殊說明集合冪級數間乘法定義為集合不交並卷積 子集卷積 對於集合不交並卷積,常見的處理方法是設出佔位多項式,對兩維分別卷積。實際上這兩維是十分獨立的,類似於二元生成函式的兩個形式冪。因此針對集合冪級數進行的運算,由於我們在佔位維上的運算就是普...
學習筆記 FWT及集合冪級數入門
相比與 rm ntt fft 中的加法卷積,這裡支援了位運算卷積,原理基於集合冪級數研究 vfk 的 閱讀沒有任何門檻,所以就不抄一遍了 code displayinline void and int f,int lim,int opt void operator const node p node...
將y arctanx展開為x的冪級數
y arctanx,則x tany arctanx bai 1 tany tany siny cosy cosycosy siny siny cos y 1 cos y 則arctanx cos y cos y sin y cos y 1 1 tan y 1 1 x 故最終答案是1 1 x 這一步求...