nssl 1458.HR 的疑惑

D e s c r i p t i o n Description Description

求出 [ 1 , n ] [1,n] [1,n]中有多少数能被表示成 a b ( b > 1 ) a^b(b>1) ab(b>1)的形式

数据范围: n ≤ 1 0 18 n\leq 10^{18} n1018


S o l u t i o n Solution Solution

首先所有的完全平方数肯定是要算上的,它们的个数就是 ⌊ n ⌋ \lfloor \sqrt n\rfloor n

然后我们就可以暴力算了,因为完全立方数最多只有 1 0 6 10^6 106个,我们完全可以把所以已经选了的数标记了就行

然而会存在 2 2 3 2^{2^3} 223 2 3 2 2^{3^2} 232这种情况会算重,所以我们应只用质数来计算

注意 2 64 > 1 0 18 2^{64}>10^{18} 264>1018,所以只需要筛到六十四就行辽

时间复杂度: O ( 1 ) O(1) O(1)【滑稽】


C o d e Code Code

#include
#include
using namespace std;long long n,ans,z;
bool v[100],M[1001000];
signed main()
{
	scanf("%lld",&n);ans=(long long)pow(n,0.5);
	for(register int i=1;i*i<=1e6;i++) M[i*i]=1;
	for(register int i=2;i<=64;i++)
	{
		if(v[i]) continue;
		for(register int j=i;j<=64;j+=i) v[j]=true;
		if(i==2) continue;
		for(register int k=1;pow(k,i)<=n;k++) if(!M[k]) ans++;
		for(register int k=1;(z=pow(k,i))<=n;k++) if(z<=1e6) M[z]=true;else break;
	}
	printf("%lld",ans);
}

你可能感兴趣的:(数论,筛)