题目大意
记 f ( n ) f(n) f(n) 表示 ∑ d ∣ n , gcd ( n , n d ) = 1 d \sum_{d|n,\ \gcd(n,\frac nd)=1}d ∑d∣n, gcd(n,dn)=1d,给定 n n n,求 ∑ i = 1 n f ( i ) m o d 1 0 9 + 7 \sum_{i=1}^n f(i) \bmod 10^9+7 ∑i=1nf(i)mod109+7。
n
≤
1
0
12
n \le 10^{12}
n≤1012
多测,10 组数据,20s,32768K 。
\\
\\
\\
首先
明眼人一看就有
f
(
n
)
=
∏
i
=
1
m
(
1
+
p
i
c
i
)
,
其
中
n
=
p
1
c
1
p
2
c
2
⋯
p
m
c
m
f(n) = \prod_{i=1}^m(1+p_i^{c_i}),其中\ n=p_1^{c_1}p_2^{c_2}\cdots p_m^{c_m}
f(n)=i=1∏m(1+pici),其中 n=p1c1p2c2⋯pmcm
这显然是个积性函数。
解法1
一看,积性函数求和;
再一看,
f
(
p
)
=
1
+
p
f(p)=1+p
f(p)=1+p,意味着 min25 第一步就是求个质数和+质数个数;
再再一看,给了 20s。
行,min25,不跟你多 BB
。。。
。。。
。。。
(半天后)
。。。
WOC,0202 年了居然还有内存 32MB 的题!!???
解法2
于是乎 min25 出于它不可压缩的至少 40MB 的内存,惨遭毒手。。。
所幸积性函数求和不止一种方法。这里用的是 powerful number,用这个到后面化简起来巨优秀。
先访问这里学一下 powerful number
(第一次学就写详细点。。。)
观察到
f
(
p
)
=
1
+
p
f(p)=1+p
f(p)=1+p,能跟这个形式凑上的,马上想到
σ
(
n
)
=
∑
d
∣
n
d
\sigma(n)=\sum_{d|n}d
σ(n)=∑d∣nd 。
于是构造
h
(
n
)
=
f
(
n
)
σ
(
n
)
h(n)=\frac{f(n)}{\sigma(n)}
h(n)=σ(n)f(n)(狄利克雷卷积的除法),这个
h
(
n
)
h(n)
h(n) 就会满足只在 powerful number 处有非
0
0
0 值。推一下发现这个
h
(
n
)
h(n)
h(n) 长得很好看:
h
(
p
c
)
=
{
1
,
c
=
0
−
p
,
c
=
2
0
,
else
h(p^c)=\begin{cases} 1 &, c=0 \\ -p &, c=2 \\ 0 &, \text{else} \end{cases}
h(pc)=⎩⎪⎨⎪⎧1−p0,c=0,c=2,else
进一步有
h
(
n
)
=
{
μ
(
n
)
⋅
n
,
n
是
完
全
平
方
数
0
,
else
h(n)=\begin{cases} \mu(\sqrt n) \cdot \sqrt n & , n\ 是完全平方数 \\ 0 &, \text{else} \end{cases}
h(n)={μ(n)⋅n0,n 是完全平方数,else
设
S
σ
(
n
)
=
∑
i
=
1
n
σ
(
i
)
S_{\sigma}(n) = \sum_{i=1}^n \sigma(i)
Sσ(n)=∑i=1nσ(i),于是有:
∑
i
=
1
n
f
(
i
)
=
∑
i
=
1
n
∑
j
=
1
⌊
n
i
⌋
h
(
i
)
σ
(
j
)
=
∑
i
=
1
n
h
(
i
)
⋅
S
σ
(
⌊
n
i
⌋
)
=
∑
i
=
1
⌊
n
⌋
μ
(
i
)
⋅
i
⋅
S
σ
(
⌊
n
i
2
⌋
)
\begin{aligned} \sum_{i=1}^n f(i) &= \sum_{i=1}^n \sum_{j=1}^{\lfloor \frac ni \rfloor} h(i)\sigma(j) \\ &= \sum_{i=1}^n h(i) \cdot S_{\sigma}(\lfloor \frac ni \rfloor) \\ &= \sum_{i=1}^{\lfloor \sqrt n \rfloor} \mu(i) \cdot i \cdot S_{\sigma}(\lfloor \frac{n}{i^2} \rfloor) \end{aligned}
i=1∑nf(i)=i=1∑nj=1∑⌊in⌋h(i)σ(j)=i=1∑nh(i)⋅Sσ(⌊in⌋)=i=1∑⌊n⌋μ(i)⋅i⋅Sσ(⌊i2n⌋)
前面
μ
\mu
μ 线筛出来,后面
S
σ
(
⌊
n
i
2
⌋
)
S_{\sigma}(\lfloor \frac{n}{i^2} \rfloor)
Sσ(⌊i2n⌋) 每次分块求:
S
σ
(
m
)
=
∑
i
=
1
m
i
⌊
m
i
⌋
S_{\sigma}(m) = \sum_{i=1}^m i \lfloor \frac mi \rfloor
Sσ(m)=i=1∑mi⌊im⌋
总的时间复杂度为
∑
i
=
1
n
⌊
n
i
2
⌋
=
n
∑
i
=
1
n
1
i
=
O
(
n
ln
n
)
\sum_{i=1}^{\sqrt n} \sqrt{\lfloor \frac{n}{i^2} \rfloor} = \sqrt n \sum_{i=1}^{\sqrt n} \frac 1i = O(\sqrt n \ln n)
i=1∑n⌊i2n⌋=ni=1∑ni1=O(nlnn)
以优秀的空间+时间打爆一切。
代码
#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int maxsqrtn=1e6+5, maxp0=80000, maxw0=2e6+5;
const LL mo=1e9+7, inv2=5e8+4;
LL n;
int sqrtn;
int p[maxp0],p0,mu[maxsqrtn];
bool bz[maxsqrtn];
void Prime(int n)
{
mu[1]=1;
fo(i,2,n)
{
if (!bz[i]) p[++p0]=i, mu[i]=-1;
fo(j,1,p0)
{
if ((LL)i*p[j]>n) break;
bz[i*p[j]]=1;
if (i%p[j]==0) break;
else mu[i*p[j]]=-mu[i];
}
}
}
inline LL sum(LL x,LL y) {return (x+y)%mo*((y-x+1)%mo)%mo*inv2%mo;}
LL S(LL n)
{
LL re=0;
for(LL i=1, j; i<=n; i=j+1)
{
LL x=n/i;
j=n/x;
(re+=sum(i,j)*x)%=mo;
}
return re;
}
int T;
int main()
{
Prime(1e6);
scanf("%d",&T);
while (T--)
{
scanf("%lld",&n);
sqrtn=sqrt(n);
LL ans=0;
fo(i,1,sqrtn) if (mu[i]!=0) (ans+=mu[i]*i*S(n/((LL)i*i)))%=mo;
printf("%lld\n",(ans+mo)%mo);
}
}