杜教筛
去年暑假学的,但是当时显然学的似懂非懂的。
希望求一个函数 \(f\) 的前缀和,考虑构造另一个函数 \(g\) 和它进行狄利克雷卷积的前缀和。
\[\sum\limits_{i=1}^n(f*g)(i)=\sum\limits_{t=1}^ng(t)S(n')
\]
考虑差分一下可以得到:
\[S(n)=\sum\limits_{i=1}^n(f*g)(i)-\sum\limits_{t=2}^ng(t)S(n')
\]
然后后者是可以数论分块解决的。以 \(\mu\) 为例,让 \(f\) 是 \(\mu\),\(g\) 是 \(I\),有结论是说 \(f*g=\varepsilon\)。然后就可以快速计算了。\(\varphi\) 也是一样的,考虑 \(\varphi*I=id\),所以也是可以做的。然后做一下记忆化(然而好写这东西没什么用),筛出前 \(10^6\) 的前缀和可以加快计算速度。板子如下,不同的只是前面两个函数的计算方法不同。
unordered_map<int,int>fan;
inline int fg(int wh){return ;}
inline int sg(int l,int r){return ;}
int solve(int wh){
if(wh<N)return sf[wh];
if(fan[wh])return fan[wh];
int an=fg(wh);
for(int l=2,r=0;l<=wh;l=r+1){
r=wh/(wh/l);
an-=sg(l,r)*solve(wh/l);
}
return fan[wh]=an;
}
然后就可以解决 模板题 了。然后在另外一道题中我们需要计算的是 \(\sum\varphi(i)i^2\)。
让 \(f=\varphi(i)id^2,g=id^2\),思考他们狄利克雷卷积的结果。
\[\sum\limits_{k|n}\varphi(k)k^2(\frac{n}{k})^2=\sum\limits_{k|n}\varphi(k)n^2=n^3
\]
所以就可以构造 \(f*g=id^3\),然后杜教筛解决啦。