https://nanti.jisuanke.com/t/30999
题意:
f(i):能拆成两个数的乘积,并且这两个数要求没有平方因子。
最后求f(1)+f(2)+f(3)+...f(n)。
思路:
我们可以发现素数的f 为2,每个大于2的数都能拆成若干个素数相乘,如果一个素数出现三次,那这个数的f肯定为0,没有相同素数时为(p为因数个数),否则为
(n为不同因子的个数,p为相同因子的对数),知道这个就能用欧拉筛法求解
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e7+10;
bool prim[maxn];
int pri[maxn];
int f[maxn];
ll ans[maxn];
void init()
{
f[1]=1;
memset(prim,false,sizeof(prim));
int cnt=0;
for(int i=2;i<maxn;i++)
{
if(!prim[i])
pri[cnt++]=i,f[i]=2;
for(int j=0;j<cnt&&pri[j]*i<maxn;j++)
{
prim[i*pri[j]]=true;
if(i%pri[j]==0)
{
if(i%(pri[j]*pri[j])==0)
f[i*pri[j]]=0;
else f[i*pri[j]]=f[i]/2;
break;
}
else f[i*pri[j]]=f[i]*2;
}
}
}
int main()
{
init();
ans[0]=0;
for(int i=1;i<maxn;i++)
ans[i]=ans[i-1]+f[i];
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
printf("%lld\n",ans[n]);
}
return 0;
}