【51Nod 1769】Clarke and math2

【51Nod 1769】Clarke and math2

题面

51Nod

题解

对于一个数论函数\(f\)\(\sum_{d|n}f(d)=(f\times 1)(n)\)

其实题目就是要求\(g=f\times 1^k\)

考虑\(1^k(n)\)怎么求,因为\(1(n)\)是个积性函数,所以\(1^k(n)\)也是个积性函数。

我们考虑对于\(n\)的每个质因子\(p\)和它的次数\(r\),求出对应函数的值。

那么就相当于在每个不同的\(i_{j-1}\)\(i_j\)中插入一个质因子,表示乘上\(p\)倍,也可以在同一个位置插。

那么根据排列组合,这个问题的答案就是\(k-1+r\choose r\),然后把每个质因数的贡献乘起来就是答案。

代码

#include <iostream> 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <cmath> 
#include <algorithm> 
using namespace std; 
const int Mod = 1e9 + 7; 
inline int gi() { 
    register int data = 0, w = 1; 
    register char ch = 0; 
    while (!isdigit(ch) && ch != '-') ch = getchar(); 
    if (ch == '-') w = -1, ch = getchar(); 
    while (isdigit(ch)) data = (10ll * data + ch - '0') % Mod, ch = getchar(); 
    return w == 1 ? data : (-data + Mod) % Mod; 
} 
int fpow(int x, int y) { 
    int res = 1; 
    while (y) { 
        if (y & 1) res = 1ll * res * x % Mod; 
        x = 1ll * x * x % Mod; 
        y >>= 1; 
    } 
    return res; 
} 
const int MAX_N = 5e5 + 5; 
int fac[25], ifc[25], C[25]; 
int N, K, f[MAX_N], g[MAX_N], h[MAX_N], cur[MAX_N]; 

int main () { 
#ifndef ONLINE_JUDGE 
    freopen("cpp.in", "r", stdin); 
#endif 
    fac[0] = 1; for (int i = 1; i <= 20; i++) fac[i] = 1ll * i * fac[i - 1] % Mod; 
    ifc[20] = fpow(fac[20], Mod - 2); 
    for (int i = 19; ~i; i--) ifc[i] = 1ll * ifc[i + 1] * (i + 1) % Mod; 
    N = gi(), K = gi(); 
    for (int i = 1; i <= N; i++) f[i] = gi(), g[i] = 1, cur[i] = i; 
    for (int i = 0; i <= 20; i++) { 
        int nw = (i + K - 1) % Mod; C[i] = ifc[i]; 
        for (int j = 0; j < i; j++) C[i] = 1ll * C[i] * (nw - j + Mod) % Mod; 
    } 
    for (int i = 2; i <= N; i++) { 
        if (cur[i] == 1) continue; 
        for (int j = i; j <= N; j += i) { 
            int k = 0; 
            while (cur[j] % i == 0) ++k, cur[j] /= i; 
            g[j] = 1ll * g[j] * C[k] % Mod; 
        } 
    } 
    for (int i = 1; i <= N; i++) 
        for (int j = i; j <= N; j += i) 
            h[j] = (h[j] + 1ll * f[i] * g[j / i]) % Mod; 
    for (int i = 1; i <= N; i++) printf("%d ", h[i]); 
    putchar('\n'); 
    return 0; 
}
posted @ 2019-11-04 15:04  heyujun  阅读(...)  评论(... 编辑 收藏