1004 素数分布 素数筛 数论

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

题目描述

素数分布函数π(n)\pi (n)π(n)表示小于或等于n的素数的数目。例如π(10)=4\pi (10)=4π(10)=4(2,3,5,7是素数)。这个函数涉及到许多高等数论的内容,甚至和黎曼猜想挂钩,目前还有很多数学家正在不断探索其中的奥秘。千里之行始于足下,现在你开始关心一个问题:在正整数域中素数的分布是怎么样的。为了探索这个问题,你需要计算出一些π(n)\pi (n)π(n)的值。

输入描述:

第一行一个整数T(T≤1000)T(T \le 1000)T(T1000),表示数据的组数。
接下来一共T行,第i+1(1≤i≤T)i+1(1 \le i \le T)i+1(1iT)行表示第i组数据。每行一个正整数n(n≤1000)n (n\le 1000)n(n1000)。

输出描述:

输出T行,第i行对应输入的第i组数据。每行一个正整数,表示π(n)\pi (n)π(n)的值。
示例1

输入

复制
1
10

输出

复制
4

分析

素数筛,筛出素数,然后二分一下答案即可知道n 前面有多少个素数,n = 0和n = 1要特判一下,因为素数筛数组里没有这两个数

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

//#define int ll
const int N = 1e5+10;
int n,m;
int primes[N];
bool st[N];
int cnt;
void get_prime() {

for(int i = 2;i<=1000;i++) {
if(!st[i]) {
primes[cnt++] = i;
}
for(int j = 0;primes[j] * i <= 1000;j++) {
st[primes[j] * i] = 1;
if(i % primes[j] == 0) break;

}
}

}

void solve()
{
cin>>n;
int l = 0,r = cnt-1;
if(n == 1|| n == 0) {
cout<<0<<endl;
rt;
}

// cout<<primes[171]<<endl;
while(l<r) {
int mid = l + r + 1>> 1;
if(primes[mid] <= n) l = mid;
else r = mid - 1;
}
cout<<l + 1<<endl;
}

signed main(){
clapping();TLE;

get_prime();
int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}

/*样例区


*/

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

 

posted @ 2022-07-24 18:23  er007  阅读(102)  评论(0编辑  收藏  举报