当代大学生的第一道数论题
2018年CCPC杭州站B题,Master of Phi 题目地址
题目大意:
给你 F ( x ) = ∑ d ∣ n n φ ( d ) ( n d ) \large F(x) = \sum_{d|n}^{n}\varphi(d)(\frac{n}{d}) F(x)=∑d∣nnφ(d)(dn) module 998244353, n 以唯一素数分解的形式给出,求 F ( x ) \large F(x) F(x) 的值。
需要用到的知识:
- φ ( x ) \large \varphi(x) φ(x)是积性函数,积性函数的狄利克雷卷积同样也是积性函数。积性函数都满足若 g c d ( n , m ) = 1 \large gcd(n,m)=1 gcd(n,m)=1, 则 f ( n m ) = f ( n ) f ( m ) \large f(nm)=f(n)f(m) f(nm)=f(n)f(m)
- φ ( x ) \large \varphi(x) φ(x)性质: n = p k \large n=p^k n=pk 时 φ ( p k ) = ( p − 1 ) p k − 1 \large \varphi(p^k)=(p-1)p^{k-1} φ(pk)=(p−1)pk−1
- φ ( x ) \large \varphi(x) φ(x)性质: n \large n n为素数是 φ ( n ) = n − 1 \large \varphi(n)=n-1 φ(n)=n−1,特殊的 φ ( 1 ) = 1 \large \varphi(1)=1 φ(1)=1
- 整数的素数唯一分解定理, n = ∏ i = 1 k p i e i \large n=\prod_{i=1}^{k} p_{i}^{e_{i}} n=∏i=1kpiei ,代入积性函数 g ( n ) = ∑ d ∣ n f ( d ) \large g(n)=\sum_{d|n}f(d) g(n)=∑d∣nf(d)时可以分解为 g ( n ) = ∏ i = 1 k ∑ j = 0 e i f ( p i j ) \large g(n)=\prod_{i=1}^{k}\sum_{j=0}^{e_{i}}f(p_{i}^{j}) g(n)=∏i=1k∑j=0eif(pij)
解题过程:
f
(
n
)
=
∑
d
∣
n
φ
(
d
)
(
n
d
)
\large f(n)=\sum_{d|n}\varphi(d)(\frac{n}{d})
f(n)=d∣n∑φ(d)(dn)
由上 4 对
n
\large n
n进行素数分解,得
f
(
n
)
=
∏
i
=
1
k
∑
j
=
1
e
i
φ
(
p
i
j
)
(
p
i
e
i
p
i
j
)
\large f(n)=\prod_{i=1}^{k}\sum_{j=1}^{e_{i}}\varphi(p_{i}^{j})(\frac{p_{i}^{e_{i}}}{p_{i}^{j}})
f(n)=i=1∏kj=1∑eiφ(pij)(pijpiei)
由 2 对上式化简,得
f
(
n
)
=
∏
i
=
1
k
∑
j
=
1
e
i
(
p
i
−
1
)
p
i
j
−
1
(
p
i
e
i
p
i
j
)
\large f(n)=\prod_{i=1}^{k}\sum_{j=1}^{e_{i}}(p_{i}-1)p_{i}^{j-1}(\frac{p_{i}^{e_{i}}}{p_{i}^{j}})
f(n)=i=1∏kj=1∑ei(pi−1)pij−1(pijpiei)
化简,得
f
(
n
)
=
∏
i
=
1
k
(
p
i
−
1
)
p
i
e
i
−
1
∑
j
=
1
e
i
\large f(n)=\prod_{i=1}^{k}(p_{i}-1)p_{i}^{e_{i}-1}\sum_{j=1}^{e_{i}}
f(n)=i=1∏k(pi−1)piei−1j=1∑ei
上面的式子中没有
j
=
0
\large j=0
j=0的情况,所以每个连乘中每项还要加一项
p
i
e
i
\large p_{i}^{e_{i}}
piei,然后再乘,得
f
(
n
)
=
∏
i
=
1
k
(
p
i
−
1
)
p
i
e
i
−
1
e
i
+
p
i
e
i
\large f(n)=\prod_{i=1}^{k}(p_{i}-1)p_{i}^{e_{i}-1}e_{i}+p_{i}^{e_{i}}
f(n)=i=1∏k(pi−1)piei−1ei+piei
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5+500;
const ll mod = 998244353;
ll ans,p,e;
int n;
ll po(ll a,ll b){
ll an = 1;
while(b){
if(b&1) an = (an*a)%mod;
a = (a*a)%mod;
b>>=1;
}
return an;
}
int main(){
int _;scanf("%d",&_);
while(_--){
scanf("%d",&n);
ans = 1;
while(n--){
scanf("%lld%lld",&p,&e);
ll t = po(p,e-1);
ll temp = (((((p-1)*t)%mod)*e)%mod+po(p,e))%mod;
ans = (ans * temp)%mod;
}
printf("%lld\n",ans);
}
return 0;
}