給定f(
x)在[1,
n]上的取值,求函式:g(
x)=∑
i1|x
∑i2|
i1…∑
ik|i
k−1f
(ik)
在[1,n
] 上的取值。
容易發現,g=
1k×f
,直接用狄利克雷卷積快速冪即可。
顯然,p
的所有因子在整除關係
|下構成乙個偏序,可以等價地轉化為一張帶自環而無其他環的圖。則從i1
=p開始的序列i1
,i2,
…,ik
與有向無環圖上從
p 開始長度為
k的路徑一一對應。
考慮求從
p 開始長度為
k的路徑所有終點位置的和h[
p][k
] ,容易寫出方程:h[
p][k
]=∑i
|ph[
i][k
−1]h
[p][
1]=d
at[p
] 然而這個dp的狀態規模是o(
n2) 的,考慮原因:存在很長的鏈是因為可以多次在乙個數上重複(即在自環上走)。設h[
p][k
] 為長度為從
p 開始長度為
k的所有不經過自環的終點位置的和,則:h[
p][k
]=∑i
|p,i
[i][
k]顯然k≤
lgk,現在向路徑上插入自環。考慮h[
n][p
] 對h[
n][k
] 的貢獻,p≤
k 。需要在
p 個位置上插入k−
p個自環,用隔板法分析可知為:(p
+(k−
p)−1
p−1)
=(k−
1p−1
) ,因此:h[
n][k
]=∑p
h[n]
[p](
k−1p
−1)
而答案g(n
) 等於
n 的所有因子的h[
n][k
]的和,即:g(
n)=∑
i|nh
[i][
k]自此問題得以解決。複雜度o(
nlg2n
) 。
#include
using
namespace
std;
const
int maxn = 100005;
struct node edge[maxn*20];
int head[maxn], top = 0;
inline
void push(int i, int j)
, head[i] = top; }
int n, k;
void init()
long
long f[maxn][20], a[maxn];
const
long
long mod = 1000000007ll;
long
long fac[maxn], inv[maxn], g[maxn], g2[maxn];
long
long power(int a, long
long n)
inline
long
long choose(int k, int k)
void init_c()
void dp()
}for (register
int i = 1; i <= n; i++) // cerr << endl;
memset(g2, 0, sizeof g2);
for (register
int i = 1; i <= n; i++)
for (register
int j = 1; j*i <= n; j++)
(g2[j*i] += g[i]) %= mod;
for (int i = 1; i <= n; i++)
printf("%lld ", g2[i]);
puts("");
}int main()
狄利克雷卷積 狄利克雷卷積學習筆記
前置知識 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...
狄利克雷卷積
積性函式 f 和 g 狄利克雷卷積的形式 f ast g n sum limits f d g frac 或者 f ast g n sum limits f i g j 它滿足證明 f ast g ast h sum limits sum limits f d g frac h frac 等同於 f...
狄利克雷卷積
狄利克雷卷積 是定義在數論函式間的一種二元運算,可以定義為 f g n sum limits f x g y 或 f g n sum limits f d g frac 若 f,g 均為積性函式,則 f g 也是積性函式。顯然 f g 1 f 1 g 1 1 設 n perp m 則 begin f...