这么反演一通
转化为abc<=n的解数 [暴力] HDU 4473 Exam
a 以立方根的复杂度枚举一通再讨论下就好了
既然糖老师强调复杂度分析 那就来分析分析
对于子问题 abc<=n
复杂度是n的2/3次的
再套一重外循环是n的5/6次?
肯定是我分析错了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include <tr1/unordered_map>
typedef long long ll;
using namespace std;
using namespace std::tr1;
const int maxn=10000000;
int prime[1000000],num;
int vst[maxn+5],miu[maxn+5];
inline void Pre(){
miu[1]=1;
for (int i=2;i<=maxn;i++){
if (!vst[i]) prime[++num]=i,miu[i]=-1;
for (int j=1;j<=num && (ll)i*prime[j]<=maxn;j++){
vst[i*prime[j]]=1;
if (i%prime[j]==0){
miu[i*prime[j]]=0;
break;
}
miu[i*prime[j]]=miu[i]*miu[prime[j]];
}
}
}
inline ll calc(ll n){
ll ans=0;
for(ll a=1;a*a*a<=n;a++)
for(ll b=a;a*b*b<=n;b++){
ll c=n/(a*b);
if(c<b) break;
if(a==b)
ans+=(c-b)*3+1;
else
ans+=(c-b)*6+3;
}
return ans;
}
inline ll Solve(ll n){
if (!n) return 0;
ll ret=0;
for (ll k=1;k*k<=n;k++)
if (miu[k])
ret+=miu[k]*calc(n/k/k);
ret=(ret+n)/2;
return ret;
}
int main(){
ll l,r;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%lld%lld",&l,&r); Pre();
printf("%lld\n",Solve(r)-Solve(l-1));
return 0;
}