一道狄利克雷卷積模板題的組合做法

2021-08-01 21:06:54 字數 2203 閱讀 1484

給定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...