設有四個數論函式\(\bf h,f,g,s\)滿足\(\mathbf h=\mathbf f*\mathbf g\),\(\mathbf s(n)=\sum\limits_^n \mathbf f(i)\)
\[\sum\limits_^n \mathbf h(i)=\sum\limits_^n\sum\limits_\mathbf g(d)\mathbf f (\frac)
\]\[=\sum_^n\mathbf g(i)\sum_^\rfloor }\mathbf f(i)
\]\[=\sum_^n\mathbf g(i)\mathbf s(\lfloor\frac\rfloor)
\]\[=\mathbf g(1)\mathbf s(n)+\sum_^n \mathbf g(i) \mathbf s(\lfloor\frac\rfloor)
\]於是有
\[\mathbf g(1)\mathbf s(n)=\sum_^n \mathbf h(i) -\sum_^n \mathbf g(i) \mathbf s(\lfloor\frac\rfloor )
\]我們就利用這個式子進行求和,構造乙個好求的\(\mathbf h\)和\(\mathbf g\)
比如\(\epsilon=\mu*\mathbf1\),則\(\mathbf s(n)=1-\sum\limits_^n\mathbf s(\lfloor\frac\rfloor )\)
這裡的複雜度我沒仔細研究,放結論了。
直接進去遞迴進行求解的複雜度是\(o(n^})\)的,預處理篩出的前\(o(n^})\)的所求函式的字首和可以達到平衡,複雜度\(o(n^})\)
事實上預處理稍微大於\(n^}\)的話效率會更快。
存東西最好手寫\(\tt\)或者用\(\tt\),別用\(\tt\)
code:
#include #include #define ll long long
std::unordered_map phi,mu;
const int n=3e6;
int pri[n+10],ispri[n+10],cnt;
ll fphi[n+10],fmu[n+10];
void init()
for(int j=1;j<=cnt&&i*pri[j]<=n;j++)
else}}
for(int i=2;i<=n;i++)
fmu[i]+=fmu[i-1],fphi[i]+=fphi[i-1];
}ll calphi(int n)
return phi[n]=ret;
}ll calmu(int n)
return mu[n]=ret;
}int main()
return 0;
}
學習筆記 杜教篩
這是一種通過建構函式 g x 來求一類積性函式字首和的做法,方法比較精妙 考慮我們要求函式 f 的字首和 s n sum n f i 已經有構造好的積性函式 g 將 f,g 做狄利克雷卷積,此時推式子可以得到 sum n f g k sum n sum f d g frac sum n g d su...
學習筆記 杜教篩
入門好部落格 杜教篩 pengym 求一些方便構造卷積形式的積性函式的字首和 不是積性函式如果可以變成卷積形式也可以做 構造h f g,然後推h的字首和,就可以把f字首和遞迴處理 所以,h,g字首和必須可以快速求 有時候,杜教篩的思想也值得借鑑。也是一些題目的解決方法。由於可以記憶化,所以在多次詢問...
學習筆記 杜教篩
dirichlet 卷積,數論分塊 杜教篩用於解決數論函式 f n 的字首和問題,即求 s n sum f i 對於任意數論函式 g n 都有 sum sum f d g left frac right sum g i s left left lfloor frac right rfloor rig...