题目链接:
https://nanti.jisuanke.com/t/30999
代码:
线性筛找出最小的素数来,之后递推找规律求解。
#include <iostream>
#include <cstring>
using namespace std;
const int inf=2e7+10;
int flag[inf+10],ans[inf+10];
int temp[inf+10];
int main()
{
int k=0;
memset(flag,0,sizeof(flag)); //所有的素数都是可以分解为是一连串的质数之积。
for(int i=2;i<=inf;i++)
{
if(!flag[i])
{
ans[k++]=i;
temp[i]=i;
}
for(int j=0;j<k;j++)
{
if(i*ans[j]>inf)
break;
flag[i*ans[j]]=1;
temp[i*ans[j]]=ans[j];
if(i%ans[j]==0) //尽快的跳出。
{
break;
}
}
}
/*for(int i=0;i<k;i++)
cout<<ans[i]<<" ";
cout<<endl;*/
memset(ans,-1,sizeof(ans));
ans[0]=0;
ans[1]=1; ans[2]=2; ans[3]=2;ans[4]=1;
int minprime;
for(int i=5; i<inf ; ++i)
{
minprime=temp[i];
if(minprime*minprime*minprime<=i && i%(minprime*minprime*minprime)==0 )
ans[i]=0;
else if( minprime*minprime<=i&&i%(minprime*minprime)==0 )
ans[i]=ans[i/( minprime*minprime) ] ;
else
ans[i]=2*ans[i/minprime];
}
for(int i=1;i<=inf;i++)
ans[i]=ans[i]+ans[i-1];
int T,a;
scanf("%d",&T);
while(T--)
{
scanf("%d",&a);
printf("%d\n",ans[a]);
}
return 0;
}