杜教篩學習筆記

2022-04-30 01:27:10 字數 1399 閱讀 8881

設有四個數論函式\(\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...