Description
求
∑i=1n2f(i)mod 998244353
其中 f(i) 表示 i 的不同质因子个数
Analysis
设
g(i)=2f(i)
,容易发现
g(i)
是积性函数,可以用线性筛法筛出来,不过没什么用
答案的表示有很多种,仔细想想
Ans=∑i=1n∑d|iμ2(d)=∑i=1n⌊n/i⌋μ2(i)
这一条是栋爷考场上写的,听说复杂度玄妙 O(n2/3) ,然而我忘记怎么推的了QAQ
听说Crazy用杜教筛强上,给 g 卷上
我自己乱推好像也推出了答案的式子
Ans=∑i=1n∑j=1,ij≤nn[(i,j)=1]
一筹莫展,于是我根据套路无中生有个 μ
=∑i=1n∑j=1⌊n/i⌋∑d|(i,j)μ(d)
内层外移,好像直接出来了。。。
=∑d=1n√μ(d)∑i=1⌊n/d2⌋⌊n/(d2i)⌋
没了?没了
复杂度粗略分析是 O(n√ ln n) ,不是很懂,但是因为 d2 增长迅速所以实践跑得挺快
Code
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(ll i=a;i<=b;i++)
#define fd(i,b,a) for(ll i=b;i>=a;i--)
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;
typedef long long ll;
const ll N=1e6+5,mo=998244353;
ll pr[N],mu[N];
bool bz[N];
void pre(ll n)
{
mu[1]=1;
fo(i,2,n)
{
if(!bz[i]) pr[++pr[0]]=i,mu[i]=-1;
fo(j,1,pr[0])
{
ll x=i*pr[j];
if(x>n) break;
bz[x]=1;
if(i%pr[j]==0){mu[x]=0;break;}
mu[x]=-mu[i];
}
}
fo(i,1,n) mu[i]+=mu[i-1];
}
ll calc(ll n)
{
ll s=0;
for(ll i=1,j;i<=n;i=j+1)
{
j=n/(n/i);
s=(s+(j-i+1)%mo*(n/i)%mo)%mo;
}
return s;
}
int main()
{
ll n,ans=0;
scanf("%lld",&n);
ll m=sqrt(n);
pre(m);
for(ll i=1,j;i<=m;i=j+1)
{
ll t=n/(i*i);
j=min(m,sqrt(n/t));
(ans+=(mu[j]-mu[i-1]+mo)%mo*calc(t)%mo)%=mo;
}
printf("%lld",ans);
return 0;
}