先撇開這題不談,通過這題我倒是發現了推了十幾道莫反後連狄利克雷字首和都沒學紮實。
狄利克雷字首和定義:\(f*1=g\),我們稱 \(g\) 是 \(f\) 的狄利克雷字首和。
給定 \(f_1,f_2...f_n\),考慮如何在 \(o(n\log\log n)\) 內求出 \(g\) 函式。
沿用高維字首和的思路,我們可以把每乙個質因子看作一維,然後套用高維字首和的求法。
對於二位字首和,我們是先累加其中一維,然後再累加另一維,形象地來說,如果把二位字首和理解為乙個二維矩陣,就是先對每行求出字首和。
那麼我們可以沿用一樣的思路求出狄利克雷字首和:
for (int i = 1; i <= cnt; ++ i)
for (int j = 1; j * prime[i] <= n; ++ j) f[j * prime[i]] += f[j];
狄利克雷字尾和:
\(g_i=\sum\limits^_f_d\),我們稱 \(g\) 是 \(f\) 的狄利克雷字尾和。
求法:與狄利克雷字首和不能說是非常相像,只能說是一模一樣
for (int i = 1; i <= cnt; ++ i)
for (int j = n / prime[i]; j; -- j) f[j] += f[j * prime[i]];
倒推狄利克雷字首和:
如果我們已知 \(f*1=g\),如何快速求出 \(f\) 函式呢?
解法:字首和的差分陣列就是原陣列,我們還是拿二維字首和舉例。首先對行做差分,得到的陣列是對應列的字首和。再做一遍差分即可。
但注意差分要從大到小做。
for (int i = 1; i <= cnt; ++ i)
for (int j = n / prime[i]; j; -- j) f[j * prime[i]] -= f[j * prime[i]];
然後我們回到這道題:求
\[\sum\limits^n_\sum\limits^m_\text^n(i,j)\sum\limits_^[i\perp k][j\perp k]k
\]\(1\le n,m\le 10^7\)。
將原式變為
\[\sum\limits^n_\sum\limits^m_\text^n(i,j)\sum\limits_^[ij\perp k]k
\]然後我們發現這個 \(\sum\limits_^[ij\perp k]k\) 很不好動,但如果 \(ij\perp k\),則 \(ij\perp ij-k\),所以這樣的 \(k\) 總是成對出現,因此 \(\sum\limits_^[ij\perp k]k=\frac\),\(ij=1\) 例外,需要特判。
我怎麼會告訴你我是打表發現的呢
於是原式化為(我們忽略那個 \(\div 2\) 和 \(ij=1\) 的特例,因為這無關緊要)
\[\sum\limits^n_\sum\limits^m_\text^n(i,j)\varphi(ij)ij
\]仍然不好動,因為 \(ij\) 很大。這個時候就只有利用 \(\varphi(ij)=\frac\)。
然後變成
\[\sum\limits^n_\sum\limits^m_\frac^(i,j)}\varphi(i)\varphi(j)ij\\
=\sum\limits^n_\frac}\sum_\mu(k)\sum^\rfloor}_\varphi(idk)idk\sum^\rfloor}_\varphi(jdk)jdk
\]令 \(f_1(i)=\sum\limits_^\rfloor}\varphi(ij)ij,f_2(i)=\sum\limits_^\rfloor}\varphi(ij)ij\),這倆玩意兒就是個狄利克雷字尾和,可以快速預處理。
列舉 \(dk\),化為
\[\sum\limits^n_f_1(i)f_2(i)\sum_\frac}\mu(\frac)
\]令 \(f(i)=\frac},g(i)=\sum\limits_\frac}\mu(\frac)\),顯然 \(g=f*\mu\)。
狄利克雷卷積要 \(o(n\log n)\) 求,無法通過本題。但 \(g=f*\mu\) 意味著 \(f=g*1\),也就是倒推狄利克雷字首和。綜上,總時間複雜度 \(o(n\log\log n)\)。
然後別忘了最後有個 \(+1\) 再 \(\div 2\)。
#include const int mod = 998244353, n = 1e7 + 5;
int qpow(int a, int b)
return ret;
}int phi[n], inv[n], prime[n / 10], cnt, f1[n], f2[n], g[n], n, m;
bool mark[10000005];
inline void add(int &x, const int y)
inline void mns(int &x, const int y)
void init(int n)
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
} }for (int i = 1; i <= n; ++ i) g[i] = 1ll * g[i] * inv[phi[i]] % mod;
for (int i = 1; i <= n; ++ i) f1[i] = 1ll * phi[i] * i % mod;
for (int i = 1; i <= m; ++ i) f2[i] = 1ll * phi[i] * i % mod;
for (register int i = cnt; i; -- i)
for (register int j = n / prime[i]; j; -- j) mns(g[j * prime[i]], g[j]);
for (register int i = 1; i <= cnt && prime[i] <= n; ++ i)
for (register int j = n / prime[i]; j; -- j) add(f1[j], f1[j * prime[i]]);
for (register int i = 1; i <= cnt && prime[i] <= m; ++ i)
for (register int j = m / prime[i]; j; -- j) add(f2[j], f2[j * prime[i]]);
}int main()
數論函式 狄利克雷卷積
開坑卷積 這裡說一下莫比烏斯函式的定義 定義兩個函式 f n g n 的狄利克雷卷積 為 f g n d nf d g nd 滿足交換律,結合律,分配律以及 f e f 都挺顯然的。這定義也是夠奇怪了,然後就可以搞很多事情 d n d n1 d 1 nd 1 1 n n d nid d 1 nd i...
狄利克雷卷積 狄利克雷卷積學習筆記
前置知識 1 常見的完全積性函式 恒等函式 i i n 1 單位函式 id id n n 元函式 epsilon epsilon n n 1 元函式卷積任何函式 f 都是 f 本身 2 常見積性函式 尤拉函式 varphi n 是小於n和n互質的自然數個數 莫比烏斯函式 mu n sigma sig...
狄利克雷過程
官方定義 令 表示乙個可測的引數空間,描述某乙個類別的引數。令h是空間 上的乙個概率測度,表示乙個正實數。對於空間 上的任意乙個有限分割 如果空間 上的乙個隨機概率分布g在這個分割中各部分上的測度服從乙個狄利克雷分布 那麼我們就稱隨機概率分布g 服從狄利克雷過程,記為 我們把 叫做集中度引數,把h叫...