如题,设$d(x)$表示$x$的约数个数,求
首先要知道约数个数的一种表示方法:
然后题目所求就变成了
化简,改变量之后式子变为
考虑莫比乌斯反演,设
考虑优化算法时间复杂度,可以预处理出$\sum_{i = 1}^N(\frac Ni)$和$\sum_{j = 1}^M (\frac Mj)$,连带着莫比乌斯函数可以直接O(N)预处理。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19inline void Init() {
U[1] = F[1] = 1 ;
for (int i = 2 ; i <= MAXN ; i ++) V[i] = true ;
for (int i = 2 ; i <= MAXN ; i ++) {
if (V[i]) U[i] = - 1, P[++ Tot] = i, F[i] = 2, G[i] = 1 ;
for (int j = 1 ; j <= Tot && i * P[j] < MAXN ; j ++) {
V[i * P[j]] = false ;
if (i % P[j] == 0) {
U[i * P[j]] = 0 ;
F[i * P[j]] = F[i] / (G[i] + 1) * (G[i] + 2) ;
G[i * P[j]] = G[i] + 1 ;
break ;
} else
U[i * P[j]] = - U[i], F[i * P[j]] = (F[i] << 1), G[i * P[j]] = 1 ;
}
}
for (int i = 1 ; i <= MAXN ; i ++)
S[i] = S[i - 1] + U[i], Sum[i] = Sum[i - 1] + F[i] ;
}
问题答案化简为$f(1)$。反演后得到
进行数论分块就可以了,总体时间复杂度$O(T\sqrt N)$,其中T为数据组数。
1 |
|