1006 漂亮数 素数筛性质:筛法过程中本身就有一个素数 前缀和预处理 数论

链接:https://ac.nowcoder.com/acm/contest/26656/1006
来源:牛客网

题目描述

小红定义一个数满足以下条件为“漂亮数”:

1. 该数不是素数。
2. 该数可以分解为2个素数的乘积

4 是漂亮数,因为 4=2*2
21 是漂亮数,因为 21=3*7
30 不是漂亮数,因为 30=2*3*5
73 不是漂亮数。因为 73 本身即是素数。
输入 l l\ l  和 r r\ r  ,请你输出 [l,r] [l,r]\ [l,r]  闭区间中有多少个漂亮数。

输入描述:

第一行输入一个正整数 t t\ t  ,代表有 t t\ t  次询问
两个正整数 l l\ l  和 r r\ r ,用空格隔开。
 
1≤t≤1051 \leq t \leq 10^51t105
1≤l≤r≤1081 \leq l \leq r \leq 10^81lr108

输出描述:

共输出 t t\ t  行,每行为一个整数,代表 l l\ l  到 r r\ r  中漂亮数的数量。
示例1

输入

复制
1
150 200

输出

复制
12

分析

素数筛中primes[j] 本身就是一个素数,如果i 也是素数,primes[j] * i 就是漂亮数。

同一个漂亮数,有没有可能是另外两个素数的乘积呢? 质因数分解,既然两个质数的乘积就是这个数,那就不会有别的质数的乘积是这个数。

然后前缀和预处理一下,得到每个区间内漂亮数的数量

//-------------------------代码----------------------------

//#define int ll
const int N = 1e8+10;
int n,m;
int primes[N],res[N],cnt;
bool st[N];

void solve()
{
int l,r;
cin>>l>>r;
cout<<res[r] - res[l - 1]<<endl;
}

signed main(){
clapping();TLE;

for(int i = 2;i<=N;i++) {
if(!st[i]) {
primes[cnt ++ ] = i;
}
for(int j = 0;primes[j] * i <= N ;j ++) {
st[primes[j] * i] = 1;
if(!st[i])res[primes[j] * i] = 1;
if(i % primes[j] == 0) break;
}
}
for(int i = 1;i<=N;i++) {
res[i] += res[i-1];
}
int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-07-24 20:01  er007  阅读(75)  评论(0编辑  收藏  举报