我们要求的是这个:
我们切换一下枚举次序:[gcd(i,j)=1]表示如果i,j的gcd=1,则为1,否则为0
前面很好搞,我们单独搞一下后面的式子:令f(x):
令F(x):(后面那个式子很明显能看出来)
反演一下:
我们要的是f(1),代换:
令g(m):
则:
接下来我们用整除分块求,然后再套一个整除分块求g(m)就好了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e7+5,mod=998244353;
int vis[maxn],pri[maxn],mu[maxn],cnt;
void get_mu(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i])
pri[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&pri[j]*i<=n;j++)
{
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
mu[pri[j]*i]=-mu[i];
}
}
for(int i=1;i<=n;i++)
mu[i]=(mu[i-1]+mu[i]);//求莫比乌斯函数前缀和
}
void add(ll& x,ll y)
{
x=(x+y)%mod;
}
int solve(int n)
{
ll ans=0;
for(int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
add(ans,1ll*(n/l)*(n/l)%mod*(mu[r]-mu[l-1]+mod));
}
return ans;
}
int main()
{
get_mu(1e7);
int n;
ll ans=0;
cin>>n;
for(int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
add(ans,1ll*solve(n/l)*(mu[r]-mu[l-1]+mod));
}
printf("%lld\n",ans);
}