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;
}