學習筆記 杜教篩

2021-09-25 13:18:56 字數 1723 閱讀 6844

這是一種通過建構函式 \(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)\sum_^\rfloor} f(k) \\ = \sum_^n g(d)s(\lfloor\frac\rfloor) \]

進一步觀察發現:

\[ s(n) =\sum_^n(f*g)(k) - \sum_^n g(d)s(\lfloor\frac\rfloor) \]

對於前面部分要求快速\(o(1)\)得到 \((f*g)\) 的字首和。

對於後面部分需要計算的 \(s(\lfloor\frac\rfloor)\) 不超過 \(2\sqrt\) 個,套用除數函式的那個證明即可。

先套用主定理再積分一下會發現這樣做的複雜度是 \(o(n^})\) 的,如果能線性預處理出前 \(n^}\) 項的 \(s\) ,那麼複雜度就是 \(o(n^})\) 。

對於尤拉函式 \(\phi\) 求字首和 \(s(n) = \sum_^n \phi(i)\) ,以及莫比烏斯函式 \(\mu\) 求字首和,\(s(n) = \sum_^n \mu(i)\) 均可以用恒等函式 \(i(n)=1\) 來做 \(g\)。

因為可以證明得到以下等式:

\[ \phi * 1 = id \\ \mu * 1 = e=[n=1] \]

這兩者的字首和都可以 \(o(1)\) 計算。

code

/*program by mangoyang*/

#include#define inf (0x7f7f7f7f)

#define max(a, b) ((a) > (b) ? (a) : (b))

#define min(a, b) ((a) < (b) ? (a) : (b))

typedef long long ll;

using namespace std;

template inline void read(t &x)

const int lim = 10000005;

mapansmiu;

mapansphi;

ll sphi[lim];

int prime[lim], smiu[lim], tot, m;

inline int getmiu(int n)

return ansmiu[n] = ans;

}inline ll getphi(int n)

return ansphi[n] = ans;

}signed main()

sphi[i*prime[j]] = sphi[i] * (prime[j] - 1);

smiu[i*prime[j]] = -smiu[i];}}

for(int i = 2; i < lim; i++)

sphi[i] += sphi[i-1], smiu[i] += smiu[i-1];

read(m);

for(int i = 1, x; i <= m; i++)

read(x), cout << getphi(x) << " " << getmiu(x) << endl;

return 0;

}

學習筆記 杜教篩

入門好部落格 杜教篩 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...

杜教篩學習筆記

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