//题意:SPOJ-SQFREE,SPOJ4168求1e14内有多少个无平方因子数
//思路:莫比乌斯函数的性质。。实际上就是mu[i]^2的前缀和S
//然而直接搞会超时,S有Osqrtn的求法。公式的证明是容斥。
#include
#include
#include
using namespace std;
#define ll long long
const int N=1e7+5;
int prime[N],primesize,mu[N];
int sum[N];
bool isprime[N];
//线性筛可以预处理prime和isprime
//在这过程中可以预处理积性函数f, 比如mu phi d
//4个加代码的地方要自己加 要取模就每一步都取模
//比如预处理欧拉函数 预处理mu,均有模板
//反演的题会用到这个
//prime从prime[1]开始
void getlist(int listsize)//预处理的范围 指i*prime[j]的最大值
{
memset(isprime,1,sizeof(isprime));
isprime[1]=false;
mu[1]=1;
mu[0]=0;
//A从2开始,所以这里加f(1)=?;
for(int i=2; i<=listsize; i++)
{
if(isprime[i])
{
prime[++primesize]=i;
//B加代码 质数的情况
mu[i]=-1;
}
//这里的prime[j]一定是最小质因子
for(int j=1; j<=primesize&&i*prime[j]<=listsize; j++)
{
isprime[i*prime[j]]=false;
if(i%prime[j]==0)
{
//C加代码 不互素的情况 一般考虑f(p^k)与p的关系
mu[i*prime[j]] = 0;
break;
}
else
{
//D加代码 互素的情况
mu[i*prime[j]] = -mu[i];
}
}
//E可加前缀和代码
// mu[i]+=mu[i-1];
}
// sum[0]=0;
// for(int i=1; i<=N; i++)
// sum[i]=mu[i]+sum[i-1];
}
int main()
{
getlist(N);//
// for(int i=1; i<=100; i++)
// cout<<i<<" "<<mu[i]<<endl;
int T=0;
scanf("%d",&T);
while(T--)
{
ll n;
scanf("%lld",&n);
ll ans=0;
int next=0;
for(ll i=1; i<=(ll)sqrt(n); i++)
{
// next=n/(n/(i*i));
ans+=1ll*(n/(i*i))*(mu[i]);
}
printf("%lld\n",ans);
}
} sss 补充:公式推导


本文介绍SPOJ-SQFREE题目求解方法,利用莫比乌斯函数的性质,通过线性筛预处理质数及mu值,并采用容斥原理计算1e14内无平方因子数的数量。
1839

被折叠的 条评论
为什么被折叠?



