一开始把式子推到欧拉函数上去 半天之后才发现自己搞错了。。。
重新推了一下发现就是莫比乌斯反演
暴力可过。。。
主要就是把式子变形一下就好了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll n;
const
int Maxn=50001;
ll Stack[Maxn],Cur;
int Mu[Maxn],Prime[Maxn],tot;
bool Check[Maxn];
inline void Div(ll n)
{
ll i;
Cur=0;
for(i=1;i*i<n;i++)
if(n%i==0)
Stack[++Cur]=i,Stack[++Cur]=n/i;
if(i*i==n)
Stack[++Cur]=i;
sort(Stack+1,Stack+Cur+1);
}
int main()
{
scanf("%lld\n",&n);
ll i,j,k;
Mu[1]=1;
for(i=2;i<Maxn;i++)
{
if(!Check[i])Prime[++tot]=i,Mu[i]=-1;
for(j=1;(k=Prime[j]*i)<Maxn;j++)
{
Check[k]=true;
if(i%Prime[j]==0){Mu[k]=0;break;}
Mu[k]=-Mu[i];
}
}
ll a,b,last,Ans=0,Con;
for(b=1;b*(b+1)<=n;b++)
{
Div(b);
a=1;
while(a<b&&b*(a+b)<=n)
{
last=min(n/(n/b/(a+b))/b-b,b-1);
Con=0;
for(k=1;Stack[k]<=Cur;k++)
Con+=Mu[Stack[k]]*(last/Stack[k]-(a-1)/Stack[k]);
Ans+=n/b/(a+b)*Con;
a=last+1;
}
}
printf("%lld\n",Ans);
}