1. 程式人生 > 實用技巧 >積性函式求和

積性函式求和

(全是套路.jpg)

題目

首先觀察這個函式,發現是 \(f(n)=\prod_j(p_j^{k_j}+1)\)(設 \(n\) 質因數分解得到 \(\prod_jp_j^{k_j}\)

然後不知怎麼想到的,就等價於 \(f(n)=\sum_{d|n} [d\bot \frac nd]d\)

終於有了比較靠譜的形式,然後就開始推:

\[\sum _{i=1}^nf(i)\\=\sum _{i=1}^n\sum_{d|i} [d\bot \frac id]d\\=\sum _{i=1}^nd\sum_{d|i} [d\bot \frac id]\\=\sum _{i=1}^nd\sum_{i=1}^{\lfloor\frac nd\rfloor} [d\bot i]\\=\sum _{i=1}^nd\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{t|d,t|i}\mu(t)\\=\sum _{i=1}^nd\sum_{t|d}\mu(t)\lfloor\frac n{dt}\rfloor\\=\sum_{T=1}^n\lfloor\frac nT\rfloor\sum _{t^2|T}\mu(t)\frac Tt\\=\sum_{t=1}^{\sqrt n}\frac {\mu(t)}t\sum_{t^2|T}T\lfloor\frac nT\rfloor\\=\sum_{t=1}^{\sqrt n}\frac {\mu(t)}t\sum_{T=1}^{\lfloor\frac n{t^2}\rfloor}Tt^2\lfloor\frac n{Tt^2}\rfloor\\=\sum_{t=1}^{\sqrt n}\mu(t)t\sum_{T=1}^{\lfloor\frac n{t^2}\rfloor}T\lfloor\frac{\lfloor\frac n{t^2}\rfloor}{T}\rfloor\\ \]

後面那個求和號顯然可以除法分塊 \(O(\frac{\sqrt n}t)\) 求,則

\[\sum_{t=1}^\sqrt n \frac{ \sqrt n}t=\sqrt n\sum_{t=1}^\sqrt n \frac{1}t\sim \sqrt n\ln n \]

總複雜度 \(O(\sqrt n\ln n)\)

然後由於毒瘤出題人把 \(n\) 出到了 \(10^{13}\),你發現你被卡常數了 \爆筋

  • 瓶頸在除法分塊,把這個除法分塊寫成比較快的版本,可以快至少一倍;
  • 注意到 \(g(n)=\sum_{T=1}^nT\lfloor\frac n{T}\rfloor=\sum_{i=1}^n\sigma(i)\)
    ,這玩意可以線篩。於是把較小的 \(g\) 拿去線篩預處理一下,省下的計算也比較可觀。

至此大概就可以過了。

放一下求 \(g\) 的函式吧(其實這裡求的是 \(2g\))。

inline int G(ll n){
	if(n<D)return sig[n];
	int res=0;ll d,e,i;
	e=n%M;
	for(i=1;i*i<=n;i++){
	  d=e,e=n/(i+1)%M;
	  res=(res+i*d*2)%M;
	  if(n>=i*(i+1))res=(res+(d-e)*(d+e+1)%M*i)%M;
	}
	return res;
}