题目描述
设(f(i))为(i)的不同的质因子个数,求(sum_{i=1}^n2^{f(i)})
(nleq{10}^{12})
题解
考虑(2^{f(i)})的意义:有(f(i))总因子,每种可以分给两个人中的一个。那么就有(2^{f(i)}=sum_{d|i}[gcd(d,frac{i}{d})=1])
然后就是简单莫比乌斯反演了。
[egin{align}
s&=sum_{i=1}^nsum_{d|i}[gcd(d,frac{i}{d})=1]\
&=sum_{i=1}^nsum_{d|i}sum_{j|d ext{&&}j|frac{i}{d}}mu(j)\
&=sum_{i=1}^nsum_{j^2|i}g(frac{i}{j^2})mu(j)\
&=sum_{j=1}^sqrt{n}mu(j)sum_{i=1}^{lfloorfrac{n}{j^2}
floor}g(i)\
&=sum_{j=1}^sqrt{n}mu(j)sum_{i=1}^{lfloorfrac{n}{j^2}
floor}lfloorfrac{n}{j^2i}
floor
end{align}
]
时间复杂度:(O(sqrt nlog n))
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll p=998244353;
ll gao(ll x)
{
ll s=0;
ll i,j;
for(i=1;i<=x;i=j+1)
{
j=x/(x/i);
s+=(x/i)*(j-i+1);
}
return s;
}
int b[1000010];
int pri[1000010];
int cnt;
int miu[1000010];
int main()
{
ll i,j;
miu[1]=1;
for(i=2;i<=1000000;i++)
{
if(!b[i])
{
pri[++cnt]=i;
miu[i]=-1;
}
for(j=1;j<=cnt&&i*pri[j]<=1000000;j++)
{
b[i*pri[j]]=1;
if(i%pri[j]==0)
{
miu[i*pri[j]]=0;
break;
}
miu[i*pri[j]]=-miu[i];
}
}
ll ans=0;
ll n;
scanf("%lld",&n);
for(i=1;i*i<=n;i++)
ans=(ans+miu[i]*gao(n/(i*i)))%p;
ans=(ans+p)%p;
printf("%lld
",ans);
return 0;
}