推公式,设$A(n)=\sum\limits_{i=1}^n\mu(i)$,令$B(n)=1$,则推出$C(n)=(A*B)(n)=[n=1]$
$$\begin{align*}\sum\limits_{i=1}^n[i=1]&=\sum\limits_{i=1}^n\sum\limits_{d|i}\mu(d)\\1&=\sum\limits_{d=1}^n\sum\limits_{\substack{d|i\\i\leq n}}\mu(d)\\1&=\sum\limits_{d=1}^n\mu(d)\left\lfloor\dfrac nd\right\rfloor\\1&=\sum\limits_{d=1}^nA\left(\left\lfloor\dfrac nd\right\rfloor\right)\\A(n)&=1-\sum\limits_{d=2}^nA\left(\left\lfloor\dfrac nd\right\rfloor\right)\end{align*}$$
然后就做完了
#include<stdio.h> #include<map> using namespace std; #define ll long long #define T 1000000 int pr[1000010],mu[1000010]; bool np[1000010]; void sieve(){ ll i,j,m=0; np[1]=1; mu[1]=1; for(i=2;i<=T;i++){ if(!np[i]){ m++; pr[m]=i; mu[i]=-1; } for(j=1;j<=m;j++){ if(pr[j]*i>T)break; np[i*pr[j]]=1; if(i%pr[j]==0)break; mu[i*pr[j]]=-mu[i]; } } for(i=2;i<=T;i++)mu[i]+=mu[i-1]; } map<ll,ll>res; map<ll,ll>::iterator it; ll dj(ll n){ if(n<=T)return mu[n]; it=res.find(n); if(it!=res.end())return it->second; ll i,las,s=1; for(i=2;i<=n;i=las+1){ las=n/(n/i); s-=(las-i+1)*dj(n/i); } return res[n]=s; } int main(){ sieve(); ll l,r; scanf("%lld%lld",&l,&r); printf("%lld",dj(r)-dj(l-1)); }