Description

求∑i=1n2f(i),其中f(i)表示i的不同质因子个数

Solution

显然,2^f(i)就是每个质因子选或者不选

那么2^f(i)等价于∑d|i[gcd(d,i/d)=1],两个互质一定不会有相同的

设c(q)=∑d|i[gcd(d,i/d)=q]
反演一下
易得c(1)=∑j=1iμ(j)g(j),其中g(j)=∑j|pc(p)
因为gcd(d,i/d)=q,d和i/d都含有q这个因子,那么一定q2|i

所以c(1)=∑j2|iμ(j)g(j)

因为g(j)=∑j|pc(p),并且j2|i
设h(i)为i的约数个数和

那么c(1)=∑j2|iμ(j)h(ij2)
总的就是∑i=1n∑j2|iμ(j)h(ij2)

交换主体,把μ提出来
∑j=1n√μ(j)∑i=1nj2h(i)

1到N的约数个数和,不妨枚举i作为约数的贡献,即i在N内倍数个数显然是⌊ni⌋

原式化为∑j=1n√μ(j)∑i=1nj2⌊nj2i⌋

前面分块,后面也分块处理
复杂度∑i=1n√n√i=n−−√lnn,非常优秀

Code

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 1000005
#define LL long long
#define mo 998244353
using namespace std;
LL n,mu[N],n1,s[N];
int pr[N],l;
bool bz[N];
void prp()
{
mu[1]=s[1]=1;
fo(i,2,n1)
{
if(!bz[i])
{
mu[i]=-1;
pr[++l]=i;
}
for(int j=1;j<=l&&pr[j]*i<=n1;j++)
{
bz[i*pr[j]]=1;
if(i%pr[j]==0)
{
mu[i*pr[j]]=0;
break;
}
else mu[i*pr[j]]=-mu[i];
}
s[i]=(s[i-1]+mu[i])%mo;
}
}
int main()
{
cin>>n;
n1=sqrt(n);
prp();
LL i=1,ans=0;
while(i<=n1)
{
LL s1=0,m=n/(i*i),i1=sqrt(n/m),p=1;
while(p<=m)
{
LL p1=m/(m/p);
s1=(s1+(m/p)*(p1-p+1)%mo)%mo;
p=p1+1;
}
ans=(ans+(s[i1]-s[i-1]+mo)%mo*s1)%mo;
i=i1+1;
}
printf("%lld\n",ans);
}