[筆記] 杜教篩
阿新 • • 發佈:2022-04-15
杜教篩
用來在非線性時間內求積性函式字首和
設現在要求積性函式 \(f\) 的字首和, 設 \(\sum \limits_{i=1}^{n} f(i) = S(n)\)。
再找一個積性函式 \(g\) ,則考慮它們的狄利克雷卷積的字首和
\[\sum\limits_{i=1}^{n}(f*g)(i) \] \[\begin{aligned} &= \sum\limits_{i=1}^{n} \sum \limits _{d|i} f(d)g(\frac{i}{d}) \\ &= \sum \limits _{d=1}^{n} g(d)\sum\limits _{i=1}^{\lfloor \frac{n}{d}\rfloor } f(i) \\ &= \sum \limits _{d=1}^{n} g(d) S(\lfloor \frac{n}{d} \rfloor) \end{aligned} \]再考慮一個式子
所以得到杜教篩的核心式子:
\[g(1)S(n)=\sum\limits_{i=1}^{n}(f*g)(i) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor) \]找到一個合適的積性函式 \(g\) ,使得可以快速算出 \(\sum\limits_{i=1}^{n}(f*g)(i)\)
inline int F_sum(int n){
if(n <= 5e6) return f[n];
int &sum = n <= m ? F[n] : F[m + ::n / n];
if(sum) return sum; sum = FG_sum(n);
for(int l(2), r; l <= n; l = r + 1)
r = n / (n / l), sum -= (G_sum(r) - G_sum(l - 1)) * F_sum(n / l);
return sum;
}
技巧
-
記憶化:
上面的求和過程中出現的都是 \(\lfloor \frac{n}{i} \rfloor\) 。開一個大小為兩倍 \(\sqrt n\) 的陣列 \(dp\) 記錄答案。
若 \(x \leq \sqrt n\) ,返回
dp[x]
,否則返回dp[sqrt n + n / x]
即可。 -
杜教篩的重點是對於要求的 \(f\),找到 \((f*g)\),滿足 \(g,(f*g)\) 的字首和都很好求出,如果沒辦法背下常見的狄利克雷卷積結果,不妨直接列舉幾個情況試試,來兩例子:
- \(f(n)=\mu(n)n^2,g(n)=n^2,(f*g)(n)=[n=1]\);
- \(f(n)=\varphi(n)n^2,g(n)=n^2,(f*g)(n)=n^3\);
題單
開始在想能不能把 i 和 j 分開
因為 \(n\le10^5,m\le10^9\),所以比較自然地想到列舉 \(n\) 去求解,然後開始考慮對某一個 \(n\) 怎麼處理。
因為 \(\varphi\) 函式的一些性質:\(n=\prod_{i=1}^qp_i^{c_i},\varphi(n)=\varphi(\prod_{i=1}^qp_i)\prod_{i=1}^qp_i^{c_i-1}\)
考慮先把 \(n\) 的質因數次數高於一次的部分都提出來,記為 \(x\),剩下的 \(\frac{n}{x}\) 記為 \(y\).
\[\begin{aligned} \sum_{i=1}^m\varphi(ni) &=x\sum_{i=1}^m\varphi(yi)\\ &=x\sum_{i=1}^m\varphi(\frac{y}{\gcd(y,i)})\varphi(i)\gcd(y,i)\\ &=x\sum_{i=1}^m\varphi(\frac{y}{\gcd(y,i)})\varphi(i)\sum_{j\mid gcd(y,i)}\varphi(j) \ (這裡用的是\ n=\sum_{i\mid n}\varphi(i))\\ &=x\sum_{i=1}^m \varphi(i) \sum_{j\mid \gcd(y,i)}\varphi(\frac{y}{j}) \ (由於\ y\ 的特殊性,y\ 與\ \gcd(y,i)\ 的因數互質,可以直接乘)\\ &=x\sum_{i=1}^m \varphi(i) \sum_{j\mid y,j\mid i}\varphi(\frac{y}{j}) \ (然後對列舉順序進行一個交換)\\ &=x\sum_{j\mid y}\varphi(\frac{y}{j})\sum_{i=1}^{\frac{m}{j}}\varphi(ji)\ (整理到此處於是可以遞迴) \end{aligned} \]總之記憶化後,複雜度是對的.