洛谷P1835-素数密度
素数密度
题目描述
给定区间
输入格式
第一行,两个正整数
输出格式
一行,一个整数,表示区间中素数的个数。
样例 #1
样例输入 #1
2 11
样例输出 #1
5
L,R本身太大,不可能直接线性筛
有一个定理是说一个合数x的最大质因子
注意:
特判L=1的情况(因为筛法是从2开始筛的)
R如果为2147483647的话,循环的时候j+=pri[i]大于R会爆int,所以j要用long long
L,R,start要用long long,因为L如果为2147483647的话,计算第一个大于等于L的 pri[i]的倍数(2倍起) 这个合数的时候会爆int
注意scanf用%lld读入L,R
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=5e4+5, MAX=1e6+5;
//----------------------------
int pri[MAXN], vis[MAXN];
bool book[MAX];
void init()
{
for(int i=2; i<MAXN; i++){
if(!vis[i])pri[++pri[0]]=i;
for(int j=1; j<=pri[0] && i*pri[j]<MAXN; j++){
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
return;
}
int main(void)
{
ll L, R, ans=0;
scanf("%lld%lld", &L, &R); //注意这里要写%lld,不然读进来的L,R数值不对
init();
if(L==1)book[0]=1; //筛法只能筛出[2, x]的合数,L=1时,需要特判
for(int i=1; i<=pri[0]; i++){
ll start;
if(pri[i]>=L){
start=2*pri[i];
}else{
if(L%pri[i]==0){
start=L;
}else{
start=(L/pri[i]+1)*pri[i];
}
}
//上面这些,是为了在L~R区间中,从第一个大于等于L的pri[i]的倍数(2倍起)开始筛合数
for(ll j=start; j<=R; j+=pri[i]){ //这里的j要用 long long,因为如果R=2147483647的话,那么j+=pri[i]后大于R的话,如果j还是int就爆成负数了,那么接下来book[j-L]就segmentation fault了
book[j-L]=1; //压缩一下空间
}
}
for(int i=0; i<R-L+1; i++){
if(book[i]==false)
ans++;
}
printf("%d\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现