2020.07.05日常总结

UVA10539 Almost Prime Numbers\color{green}{\texttt{UVA10539 Almost Prime Numbers}}

[Problem]\color{blue}{\texttt{[Problem]}}

  • 给定两个数 L,R(1L<R1012)L,R(1 \leq L < R \leq 10^{12})

  • 统计区间 [L,R][L,R](包括 LLRR)中有多少个数满足:

    • 本身不是素数
    • 只有一个素因子

[Soluntion]\color{blue}{\texttt{[Soluntion]}}

仔细思考一下就可以发现:本题其实就是求 [L,R][L,R] 中有多少个数,是一个素数的 aa 次幂,其中 aa 为大于 11 的整数。

为什么呢?第一,它本身不是素数,所以不能是素数的一次幂。第二,它不是是一个素数的幂,否则,如果它肯定不止一个素因子。

所以,我们筛出 [1,1×106][1,1\times 10^6] 中所有的素数,然后利用它们即可在很短的时间内求出解。

[code]\color{blue}{\texttt{[code]}}

const int N=1e6+100;
const int M=1e5+100;
int prime[M],tot;//素数表 
bool is_prime[N];//是否为素数 
inline void get_all_prime(int N){
	for(register int i=1;i<=N;i++)
		is_prime[i]=true;//初始化 
	is_prime[0]=is_prime[1]=tot=0;
	for(register int i=2;i<=N;i++)
		if (is_prime[i]){//不是素数免谈 
			prime[++tot]=i;//加入素数表 
			for(register int j=i;j<=N/i;j++)
				is_prime[i*j]=false;//update
		}
}
typedef long long ll;//简写 
inline int count(ll l,ll r){
	int ans=0;//初始化答案为0 
	for(int i=1;i<=tot;i++){
		ll begin=1ll*prime[i]*prime[i];
		for(ll j=begin;j<=r;j*=prime[i])
			if (j>=l) ans++;//找到一个答案 
	}
	return ans;//返回答案 
}
int test_number;ll l,r;
int main(){
	get_all_prime(1000000);
	scanf("%d",&test_number);
	while (test_number--){
		scanf("%lld%lld",&l,&r);
		printf("%d\n",count(l,r));
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章