参考博客:https://www.cnblogs.com/cjoieryl/p/10149748.html
关键是枚举最小质因子...所以构造的 S 与最小质因子有关。
代码如下:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; int const xn=1e6+5; int pri[xn],cnt,sqr; ll n,w[xn],m,f[xn]; bool vis[xn]; void init(ll mx) { for(int i=2;i<=mx;i++) { if(!vis[i])pri[++cnt]=i; for(int j=1;j<=cnt&&(ll)i*pri[j]<=mx;j++) { vis[i*pri[j]]=1; if(i%pri[j]==0)break; } } } int Id(ll x) { if(x>sqr)return n/x; return m-x+1; } ll S(ll x,int y) { if(pri[y]>x)return 0; ll ret=0; for(int i=y;i<=cnt&&(ll)pri[i]*pri[i]<=x;i++) for(ll p0=pri[i];p0*pri[i]<=x;p0*=pri[i]) ret+=S(x/p0,i+1)+(ll)pri[i]*(f[Id(x/p0)]-i+1); return ret; } ll solve(ll nw) { m=0; n=nw; sqr=sqrt(n); for(ll i=1,j;i<=n;i=j+1) {w[++m]=n/i; j=n/(n/i); f[m]=w[m]-1;} for(int j=1;j<=cnt;j++) for(int i=1;i<=m&&(ll)pri[j]*pri[j]<=w[i];i++) f[i]=f[i]-(f[Id(w[i]/pri[j])]-j+1); return S(n,1); } int main() { ll L,R; scanf("%lld%lld",&L,&R); init(sqrt(R)); printf("%lld ",solve(R)-solve(L-1)); return 0; }