目錄**
bzoj3944 : sum
hihocoder #1456 : rikka with lattice
這個演算法十分的強... 一般就是用於卡一道數論推結論題最後的\(20\)~\(30\)分... 被迫來學習qwq這個一般用來篩乙個積性函式在\(10^\)左右的字首和...
為了了解一下,可以看看 2023年國家候選隊**中的任之洲的積性函式求和的幾種方法
講講一些套路吧...
首先有ymy大佬告訴我的乙個神奇東西,這個似乎很有用...
若\(f*g=l\) (\(*\)為\(dirichlet\)卷積,下同) 若\(g\)和\(l\)易求(\(g,l\)的字首和) 則\(f\)易求 (\(f\)的字首和).即\(\displaystyle l(n)-g(1)f(n)=\sum _^n g(i) f(\lfloor\frac\rfloor)\). 證明的話可以參照後面的推導來證。
\(dirichlet\)卷積 :求\(\displaystyle \sum _^ \mu(i)\). (\(2\le a \le b \le 10 ^ \))定義兩個數論函式\(f(x),g(x)\)的\(dirichlet\)卷積 (記作\((f*g)(x)\))
\[\displaystyle (f*g)(n)=\sum _ f(d)g(\frac)
\]
這道題乙個裸的杜教篩...求個字首和,再減一下就行了...
有乙個有用的式子\(\displaystyle \sum _ \mu(d)=[n=1]\).(這個可以見我之前那篇部落格)
解法一:
直接套用之前那個式子....
\(\mu * 1=\epsilon\) 此處\(\epsilon(x) =[x=1]\) 也就是上面那個
右邊字首和都很好求\(\displaystyle \sum _^ \epsilon(i)=1\).
然後你代入到之前那個式子就有 (令\(\displaystyle m(i)=\sum_^ \mu(i)\))
\[\displaystyle 1-m(n)=\sum _^ m(\lfloor \frac \rfloor)
\]解法二
我們來手推一下上面的式子qwq
然後就有個很顯然的式子(只有\(i=1\)時候有貢獻)
\[\therefore \displaystyle \sum_^ \sum_\mu(d)=1
\]然後更換列舉項,就是考慮每個\(d\)的對於它倍數的貢獻,然後交換和式就行了。
\[\therefore \displaystyle \sum_^ \sum_^\rfloor}\mu(j)=1
\]接下來我們就可以提出\(i=1\)時的一項,也就是\(\displaystyle \sum _^\rfloor=n} \mu(j)\)
\[\displaystyle \therefore \sum _^ \mu(i)=1-\sum_^ \sum_^\rfloor}\mu(j)
\]我們如果令\(\displaystyle m(n)=\sum_^ \mu(i)\)就有和之前那個一樣的式子了
\[\displaystyle \therefore m(n)=1-\sum_^ m(\lfloor \frac\rfloor)
\]然後我們對於這個式子就可以遞迴求解了,時間複雜度是\(\theta(n^})\).
但是一定要記得要開個雜湊表儲存一下,不然時間複雜度是個錯的!!!(來自ymy大佬的原話)
這個雜湊表可以只開\(\sqrt n\)大小,因為\(\lfloor \frac \rfloor\)只有這麼多種取值.
**我看了一下fjzzq大佬的部落格 emmm... (同屆大佬太恐怖了)
我自己寫的乙個... 注意一定要全程long long
不然有詭異的錯誤....
#include #define for(i, l, r) for(register ll i = (l), _end_ = (ll)(r); i <= _end_; ++i)
#define fordown(i, r, l) for(register ll i = (r), _end_ = (ll)(l); i >= _end_; --i)
#define set(a, v) memset(a, v, sizeof(a))
using namespace std;
typedef long long ll;
bool chkmin(int &a, int b)
bool chkmax(int &a, int b)
inline ll read()
void file()
const int n = 2e6 + 1e3;
ll mu[n], limit, prime[n], cnt;
ll summu[n];
bitsetis_prime;
void mu_init(int maxn)
for (j, 1, maxn)
} }for (i, 1, maxn) summu[i] = summu[i - 1] + mu[i];
}ll size;
ll p1[n], p2[n], n;
inline ll mu_sum_(ll x)
return htr = res;
}inline ll mu_sum(ll x)
int main ()
然後在簡單講一下求\(\varphi\)(尤拉函式)的字首和吧...
求\(\displaystyle \sum_^ \varphi(i)\) 和 \(\displaystyle \sum _^ \mu(i)\). (\(n \le 2^-1\))
其實和上一道題差不多啦...多求了乙個\(\varphi\)嘛...
只要知道\(\varphi\)也有乙個類似的結論$$\displaystyle \sum_ \varphi(d)=n$$
這個我不會證明 只有乙個感性理解的方法...(來自具體數學)
你考慮所有分母為\(n\)的真分數和\(\frac\)(共有\(n\)個)
將分子和分母約去後,其他每個\(d|n\)的\(d\)都對它具有\(\varphi(d)\)的貢獻咯...
例如\(n=6\).
\[\frac,\frac,\frac,\frac,\frac,\frac
\]約分後就是
\[\frac,\frac,\frac,\frac,\frac,\frac
\]這個就比較顯然了, 應該可以寫出證明的...(太懶也太菜了..)
然後像上一題一樣的啦~ 上道題兩個解法都能用用...
\(\varphi * 1=id\)
\((id(x)=x)\) 我們令\(\displaystyle \phi(n) = \sum _ ^ \varphi(i)\).
就有乙個顯然的式子
\[\displaystyle \frac-\phi(n)=\sum_^ \phi ( \rfloor})
\]這個同上就行咯...
這題也是一道好題!~
如果想看的,就在我另一篇部落格上
無恥騙點選...
習題 杜教篩(Sum)(杜教篩)
傳送門杜教篩的板子,拿來練手 beginans sum phi i end g n 1,phi n f n h n sum phi d g frac n h n sum f d g frac 令f n sum f i h n sum h i beginh n sum h i sum sum f d ...
模板 杜教篩
杜教篩用來解決積性函式求字首和的問題。複雜度為 o n frac 適用情況 已知函式 f 求 sum f 存在 f g f 且 g,sum g,f,sum f 容易求出。常用公式 mu i n 1 varphi i id 以求 sum mu 為例。mu i n 1 sum i 1 1 1 sum i...
模板 杜教篩
杜教篩利用狄利克雷卷積來構造積性函式字首和之間的遞推式,從而利用記憶化搜尋在 n 的所有特殊點的字首和處求得 n 處的字首和。杜教篩用來處理積性函式求和問題,時間複雜度為 o n 具體證明如下 mu star 1 epsilon sum limits ni sum limits n sum limi...