分析:
首先,我们提出一个关于mu函数的简单性质:
即:
这样,我们就可以像1239一样
预处理出一部分的S函数,之后的S值用hash+记搜解决
tip
mu[1]=1 不要忘了
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
const int N=5000002;
const int maxn=1e6+5;
int mu[N],sshu[500010],tot=0,f[maxn];
bool no[N];
ll n,m,h[maxn];
void make()
{
mu[1]=1;
for (int i=2;i<N;i++)
{
if (!no[i])
{
sshu[++tot]=i;
mu[i]=-1;
}
for (int j=1;j<=tot&&sshu[j]*i<N;j++)
{
no[sshu[j]*i]=1;
if (i%sshu[j]==0)
{
mu[i*sshu[j]]=0;
break;
}
mu[i*sshu[j]]=-mu[i];
}
}
for (int i=2;i<N;i++) mu[i]=mu[i]+mu[i-1];
}
int hash(ll x)
{
ll t=x%maxn;
while (h[t]&&h[t]!=x) t=(t+1)%maxn;
return t;
}
ll cal(ll n)
{
if (n<N) return mu[n];
int l=hash(n);
if (h[l]) return f[l];
ll x=1,last;
for (ll i=2;i<=n;i=last+1) //从2开始
{
last=n/(n/i);
x=x-(last-i+1)*cal(n/i);
}
h[l]=n; f[l]=x;
return x;
}
int main()
{
make();
scanf("%lld%lld",&m,&n);
printf("%lld",cal(n)-cal(m-1));
return 0;
}