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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章