CodeForces1036 F Relatively Prime Powers(莫比乌斯容斥)

传送门

题意:

对于一个数xx,它可以表示成x=2e13e25e3....x=2^{e_1}*3^{e_2}*5^{e_3}....
现在如果一个数aa是好数它满足gcd(e1,e2,....)=1gcd(e_1,e_2,....)=1,问你2到n有多少个数是好数。

题解:

对于这题,我们可以很快想到容斥定理,只要n-1减去不满足条件的数就好啦。而不满足条件的数就是所有小于等于并且次数大于2的数。这不明显就是莫比乌斯函数的推导过程么,知道这个之后就很容易啦(不过要注意开根的精度控制)。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
bool isprime[maxn];
int prime[maxn];
int mu[maxn];
void Mu()
{
	memset(isprime,1,sizeof(isprime));
	mu[1]=1;
	int temp=0;
	for(int i=2;i<maxn;i++)
	{
		if(isprime[i]) prime[++temp]=i,mu[i]=-1;
		for(int j=1;j<=temp&&prime[j]*i<maxn;j++)
		{
			isprime[i*prime[j]]=0;
			if(i%prime[j]==0)
			{
				mu[i*prime[j]]=0;
				break;
			}
			else mu[i*prime[j]]=-mu[i];
		}
	 } 
 } 
 int a[maxn];
 long long gen(long long n,long long k){
  long long t=powl(n,1./k)-0.5;
  return t+(powl(t+1,k)-0.5<=n);
}
int main()
{
	#ifdef TEST
		freopen("input.txt","r",stdin);
    #endif
	int T,m,i,j,k;
	long long n;
	Mu();
	scanf("%d",&T);
	long long ans,temp;
	while(T--)
	{
		scanf("%lld",&n);
		ans=n-1;
		for(i=2;i<60;i++)
		{
			ans+=mu[i]*(gen(n,i)-1);
		}
		cout<<ans<<endl;
	 } 
}

Q.E.D.