题意:求 ( ∑ i = 1 n 2 f ( i ) ) m o d 998244353 \left(\sum\limits_{i=1}^n2^{f(i)}\right)\bmod 998244353 (i=1∑n2f(i))mod998244353,其中 f ( i ) f(i) f(i) 表示 i i i 的不同质因子的个数, n ≤ 1 0 12 n\leq 10^{12} n≤1012。
一开始发现 g ( x ) = 2 f ( x ) g(x)=2^{f(x)} g(x)=2f(x) 是积性函数以为能直接 min_25 筛(
结果时间爆炸(
考虑 2 f ( i ) 2^{f(i)} 2f(i) 的组合意义,得到 2 f ( i ) = ∑ j ∣ i μ 2 ( j ) 2^{f(i)}=\sum\limits_{j|i}\mu^2(j) 2f(i)=j∣i∑μ2(j)。
于是:
∑
i
=
1
n
2
f
(
i
)
=
∑
i
=
1
n
∑
j
∣
i
μ
2
(
j
)
=
∑
i
=
1
n
⌊
n
i
⌋
μ
2
(
i
)
\begin{aligned} &\sum_{i=1}^n2^{f(i)}\\ =&\sum_{i=1}^n\sum_{j|i}\mu^2(j)\\ =&\sum_{i=1}^n\lfloor\dfrac{n}{i}\rfloor\mu^2(i) \end{aligned}
==i=1∑n2f(i)i=1∑nj∣i∑μ2(j)i=1∑n⌊in⌋μ2(i)
如果我们能快速求出
μ
2
(
i
)
\mu^2(i)
μ2(i) 在
n
n
n 的基本和组上的前缀和,就能整除分块了。
注意到设
d
d
d 为
x
x
x 的最大平方因子(如
x
=
3
x=3
x=3 时
d
=
1
d=1
d=1,
x
=
24
x=24
x=24 时
d
=
2
d=2
d=2),那么:
μ
2
(
x
)
=
[
d
=
1
]
=
∑
i
∣
d
μ
(
i
)
\mu^2(x)=[d=1]=\sum_{i|d}\mu(i)
μ2(x)=[d=1]=i∣d∑μ(i)
根据
d
d
d 的定义,
x
x
x 可以写成
y
×
d
2
y\times d^2
y×d2 的形式,其中
y
y
y 没有平方因子。
那么枚举 i ∣ d i|d i∣d 相当于枚举 i 2 ∣ x i^2|x i2∣x,于是 μ 2 ( x ) = ∑ i 2 ∣ x μ ( i ) \mu^2(x)=\sum\limits_{i^2|x}\mu(i) μ2(x)=i2∣x∑μ(i)。
于是原式为:
=
∑
i
=
1
n
⌊
n
i
⌋
∑
d
2
∣
i
μ
(
d
)
=
∑
d
=
1
n
μ
(
d
)
∑
j
=
1
n
/
(
d
2
)
⌊
n
d
2
j
⌋
\begin{aligned} =&\sum_{i=1}^n\lfloor\dfrac{n}{i}\rfloor \sum_{d^2|i}\mu(d)\\ =&\sum_{d=1}^{\sqrt n}\mu(d)\sum_{j=1}^{n/(d^2)}\lfloor\dfrac{n}{d^2j}\rfloor \end{aligned}
==i=1∑n⌊in⌋d2∣i∑μ(d)d=1∑nμ(d)j=1∑n/(d2)⌊d2jn⌋
设
g
(
n
)
=
∑
i
=
1
n
⌊
n
i
⌋
g(n)=\sum\limits_{i=1}^n\lfloor\dfrac{n}{i}\rfloor
g(n)=i=1∑n⌊in⌋,于是原式为:
=
∑
d
=
1
n
μ
(
d
)
g
(
⌊
n
d
2
⌋
)
=\sum_{d=1}^{\sqrt n}\mu(d)g\left(\lfloor\dfrac{n}{d^2}\rfloor\right)
=d=1∑nμ(d)g(⌊d2n⌋)
我们暴力枚举每一个
d
d
d,并每次暴力整除分块求出
g
g
g 即可。
时间复杂度:
∑
i
=
1
n
O
(
n
i
2
)
=
∑
i
=
1
n
O
(
n
i
)
=
O
(
n
ln
n
)
\sum _{i=1}^{\sqrt n}O\left(\sqrt{\dfrac{n}{i^2}}\right)=\sum_{i=1}^{\sqrt n}O\left(\dfrac{\sqrt n}{i}\right)=O\left(\sqrt n\ln \sqrt n\right)
i=1∑nO(i2n)=i=1∑nO(in)=O(nlnn)
代码如下:
#include<bits/stdc++.h>
#define N 1000010
#define ll long long
using namespace std;
namespace modular
{
const int mod=998244353;
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int mul(int x,int y){return 1ll*x*y%mod;}
}using namespace modular;
ll n;
int sn;
int cnt,prime[N],mu[N];
bool notprime[N];
void init()
{
mu[1]=1;
for(int i=2;i<=sn;i++)
{
if(!notprime[i])
{
prime[++cnt]=i;
mu[i]=mod-1;
}
for(int j=1,x;j<=cnt&&(x=i*prime[j])<=sn;j++)
{
notprime[x]=1;
if(!(i%prime[j])) break;
mu[x]=mul(mu[i],mu[prime[j]]);
}
}
}
int g(ll n)
{
int ans=0;
for(ll l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
ans=add(ans,mul((r-l+1)%mod,(n/l)%mod));
}
return ans;
}
int main()
{
scanf("%lld",&n);
sn=sqrt(n);
init();
int ans=0;
for(int d=1;d<=sn;d++)
ans=add(ans,mul(mu[d],g(n/d/d)));
printf("%d\n",ans);
return 0;
}