Codecraft-17 and Codeforces Round 391 E. Bash Plays with Functions 积性函数
题目链接
题目大意
定义函数 f r ( n ) f_r(n) fr(n) :
- 在 r = 0 r=0 r=0时,为满足 p p p ⋅ \cdot ⋅ q = n q=n q=n , 且 g c d ( p , q ) = 1 gcd(p,q)=1 gcd(p,q)=1 的有序对 ( p , q ) (p,q) (p,q) 个数;
- 在 r r r ≥ \geq ≥ 1 1 1时, f r ( n ) = f_r(n)= fr(n)= ∑ u ⋅ v = n \sum_{u⋅v=n} ∑u⋅v=n f r − 1 ( u ) + f r − 1 ( v ) 2 f_{r-1}(u)+f_{r-1}(v) \over 2 2fr−1(u)+fr−1(v)。
一共 q q q 组询问,每组询问给出 r r r , n n n , 求 f r ( n ) f_r(n) fr(n) 模 1 0 9 + 7 10^{9}+7 109+7 的结果。
数据范围: q ≤ 1 0 6 q\leq10^{6} q≤106, 0 0 0 ≤ \leq ≤ r r r ≤ \leq ≤ 1 0 6 10^{6} 106, 1 1 1 ≤ \leq ≤ n n n ≤ \leq ≤ 1 0 6 10^{6} 106。
思路
- 积性函数
如果函数 f f f : N → R N→R N→R,满足对于任意一对互质的正整数 p p p , q q q 都有 f ( p q ) = f ( p ) f ( q ) f(pq)=f(p)f(q) f(pq)=f(p)f(q) , 则称 f f f 为积性函数。
若 f f f 为积性函数,假设 n = p 1 α 1 n={p_1}^{\alpha1} n=p1α1 p 2 α 2 {p_2}^{\alpha2} p2α2 ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⋅ \cdot ⋅ p k α k {p_k}^{\alpha k} pkαk , 则 f ( n ) = f ( p 1 α 1 ) f(n)=f({p_1}^{\alpha1}) f(n)=f(p1α1) f ( p 2 α 2 ) f({p_2}^{\alpha2}) f(p2α2) ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⋅ \cdot ⋅ f ( p k α k ) f({p_k}^{\alpha k}) f(pkαk).
设 n = p 1 α 1 n={p_1}^{\alpha1} n=p1α1 p 2 α 2 {p_2}^{\alpha2} p2α2 ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⋅ \cdot ⋅ p k α k {p_k}^{\alpha k} pkαk , 令 x x x ⋅ \cdot ⋅ y y y = n =n =n , 且 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1 . 对于所有 p i α i {p_i}^{\alpha i} piαi 在 x x x 、 y y y 中的分配都为 p i 0 {p_i}^{0} pi0 和 p i α i {p_i}^{\alpha i} piαi ,否则 g c d ( x , y ) gcd(x,y) gcd(x,y) ≠ \neq = 1 1 1 , 故 f 0 ( n ) = 2 k f_0(n)=2^{k} f0(n)=2k 。
令 α ( x ) \alpha(x) α(x)= x x x 的质因数的种类,则当 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1 时, f 0 ( x y ) = 2 α ( x y ) f_0(xy)=2^{\alpha(xy)} f0(xy)=2α(xy) = 2 α ( x ) α ( y ) =2^{\alpha(x) \alpha(y)} =2α(x)α(y)= 2 α ( x ) 2^{\alpha(x)} 2α(x) ⋅ \cdot ⋅ 2 α ( y ) 2^{\alpha(y)} 2α(y) = f ( x ) =f(x) =f(x) ⋅ \cdot ⋅ f ( y ) f(y) f(y),故 f 0 ( n ) f_0(n) f0(n) 为积性函数。
f r ( n ) = f_r(n)= fr(n)= ∑ u ⋅ v = n \sum_{u\cdot v=n} ∑u⋅v=n f r − 1 ( u ) + f r − 1 ( v ) 2 f_{r-1}(u)+f_{r-1}(v) \over 2 2fr−1(u)+fr−1(v) , 如果 u ≠ u\neq u= v v v , 则( u u u, v v v) 、( v v v, u u u) 各出现一次,否则 u = v u=v u=v , ( u u u, u u u) 出现一次但一次有两个。故, ∀ \forall ∀ d d d , d ∣ n d|n d∣n , 都出现了两次,即 f r ( n ) = f_r(n)= fr(n)= ∑ d ∣ n \sum_{d|n} ∑d∣n f r − 1 ( d ) f_{r-1}(d) fr−1(d).
令 g r ( n ) = g_r(n)= gr(n)= ∑ d ∣ n \sum_{d|n} ∑d∣n f r ( d ) f_r(d) fr(d)。
证: f r ( n ) f_r(n) fr(n)为积性函数时, g r ( n ) g_r(n) gr(n)也为积性函数。
设 p p p ⋅ \cdot ⋅ q q q = n =n =n, g c d ( p , q ) = 1 gcd(p,q)=1 gcd(p,q)=1 , 则 g r ( p q ) = g_r(pq)= gr(pq)= ∑ d ∣ p q \sum_{d|pq} ∑d∣pq f r ( d ) f_r(d) fr(d). 令 d = d 1 d=d_1 d=d1 ⋅ \cdot ⋅ d 2 d_2 d2 , d 1 d_1 d1 ∣ p |p ∣p , d 2 d_2 d2 ∣ q |q ∣q , 则 g r ( p q ) = g_r(pq)= gr(pq)= ∑ d ∣ p q \sum_{d|pq} ∑d∣pq f r ( d ) = f_r(d)= fr(d)= ∑ d 1 ∣ p , d 2 ∣ q \sum_{d_1|p,d_2|q} ∑d1∣p,d2∣q f r ( d 1 d 2 ) = f_r(d_1d_2)= fr(d1d2)= ∑ d 1 ∣ p , d 2 ∣ q \sum_{d_1|p,d_2|q} ∑d1∣p,d2∣q f r ( d 1 ) f_r(d_1) fr(d1) f r ( d 2 ) = f_r(d_2)= fr(d2)= ∑ d 1 ∣ p \sum_{d_1|p} ∑d1∣p f r ( d 1 ) f_r(d_1) fr(d1) ⋅ \cdot ⋅ ∑ d 2 ∣ q \sum_{d_2|q} ∑d2∣q f r ( d 2 ) = f_r(d_2)= fr(d2)= g r ( p ) g_r(p) gr(p) ⋅ \cdot ⋅ g r ( q ) g_r(q) gr(q) . 故当 f r ( n ) f_r(n) fr(n)为积性函数时, g r ( n ) g_r(n) gr(n)也为积性函数。
因为 f 0 ( n ) f_0(n) f0(n)是积性的不断递推 f r ( n ) f_r(n) fr(n)也将得到是积性的。
设 n = p 1 α 1 n={p_1}^{\alpha1} n=p1α1 p 2 α 2 {p_2}^{\alpha2} p2α2 ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⋅ \cdot ⋅ p k α k {p_k}^{\alpha k} pkαk , 由于 f r ( n ) f_r(n) fr(n)是积性函数,则 f r ( n ) = f_r(n)= fr(n)= f r ( p 1 α 1 ) f_r({p_1}^{\alpha1}) fr(p1α1) ⋅ \cdot ⋅ f r ( p 2 α 2 ) f_r({p_2}^{\alpha2}) fr(p2α2) ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⋅ \cdot ⋅ f r ( p k α k ) f_r({p_k}^{\alpha k}) fr(pkαk) .
写几个函数看看规律:
f 0 ( p k ) = { 1 k = 0 2 k ≥ 1 f_0(p^k)=\begin{cases} 1 & k=0 \\ 2 & k\geq 1 \\ \end{cases} f0(pk)={12k=0k≥1
f 1 ( p k ) = f_1(p^k)= f1(pk)= ∑ d ∣ p k \sum_{d|p^k} ∑d∣pk f 0 ( d ) = f_0(d)= f0(d)= 1 + 2 k 1+2k 1+2k .
⋅ ⋅ ⋅ \cdot \cdot \cdot ⋅⋅⋅
发现 f r ( p k ) f_r(p^k) fr(pk)只与 r r r 和 k k k 有关。
记: d p [ i ] [ j ] dp[i][j] dp[i][j]为 f i ( p j ) f_i(p^j) fi(pj) 。初始化: d p [ i ] [ 0 ] = 1 dp[i][0]=1 dp[i][0]=1 , d p [ 0 ] [ i ] = 2 ( i ≥ 1 ) dp[0][i]=2(i\geq1) dp[0][i]=2(i≥1).
转移时按定义来, d p [ i ] [ j ] = ∑ x = 0 j dp[i][j]=\sum_{x=0}^{j} dp[i][j]=∑x=0j d p [ i − 1 ] [ x ] dp[i-1][x] dp[i−1][x] , 加一个前缀和数组即可。
code
#include <bits/stdc++.h>
#define int long long
#define ll long long
#define pii pair<int, int>using namespace std;
const int N = 1e6 + 1000, mod = 1e9 + 7;
int prime[N], sum[N], cnt = 0, minnp[N];
bool st[N];
int dp[N][25];void is_prime(int n)
{for (int i = 2; i <= n; ++i){if (!st[i])prime[cnt++] = i, minnp[i] = i;for (int j = 0; j < cnt && i * prime[j] <= n; ++j){st[i * prime[j]] = 1, minnp[i * prime[j]] = prime[j];if (i % prime[j] == 0)break;}}
}void init()
{is_prime(1e6 + 10);for (int i = 0; i <= 1e6; ++i)dp[i][0] = 1;for (int i = 1; i <= 20; ++i)dp[0][i] = 2;sum[0] = 1;for (int i = 1; i <= 1e6; ++i){for (int j = 1; j <= 20; ++j){sum[j] = (sum[j - 1] + dp[i - 1][j]) % mod;dp[i][j] = sum[j];}}
}
void solve()
{int r, n;cin >> r >> n;int ans = 1;while (n >= 2){int num = 0, p = minnp[n];while (n % p == 0)num++, n /= p;ans = ans * dp[r][num] % mod;}// for (int i = 0; i < cnt && prime[i] <= sqrt(n); ++i)// {// int num = 0;// while (n % prime[i] == 0)// {// num++;// n /= prime[i];// }// ans = ans * dp[r][num] % mod;// }// if (n > 1)// ans = ans * dp[r][1] % mod;cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);init();int t = 1;cin >> t;while (t--)solve();return 0;
}