zoukankan      html  css  js  c++  java
  • 找素数 (素数筛+离散化)

    问题描述
      给定区间[L, R] , 请计算区间中素数的个数。
    输入格式
      两个数L和R。
    输出格式
      一行,区间中素数的个数。
    样例输入
    2 11
    样例输出
    5
    题目异常简单,可是不是很好做,l和r的范围太大了,直接暴力一定会超时,可以借鉴素数筛的思路,用素数把合数筛去,区间内的最大数是r,所以可以做因子的素数一定不大于sqrt®,所以只用把小于sqrt®的所有素数全部筛出来,再用他们去筛区间内的数,有一个问题素数筛的时候要用到一个标记数组,可是r太大了,数组开不了那么大,但是有一个条件r-l<=1e6,所以可以把整个区间离散化到区间[0,r-l]就可以了。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int inf=2147483647,N=1000010;
    int l,r;
    int prim[N],cnt;
    bool st[N];
    void init()//预处理出来所有的素数,线性筛模板
    {
    	for(int i=2;i<=sqrt(inf);i++)
    	{
    		if(!st[i]) prim[cnt++]=i;
    		for(int j=0;prim[j]<=sqrt(inf)/i;j++)
    		{
    			st[prim[j]*i]=1;
    			if(i%prim[j]==0) break;
    		}
    	}
    }
    int main()
    {
    	init();
    	memset(st,0,sizeof st);
    	cin>>l>>r;
    	for(int i=0;i<cnt;i++)
    	{
    		for(int j=(l+prim[i]-1)/prim[i];j<=r/prim[i];j++)//j是区间[l,r]内的数存在的prim[i]的倍数,左端点向上取整,左端点向下取整
    			if(j!=1)//倍数是1,所以这个数就是素数本身不能筛
    				st[prim[i]*j-l]=1;
    	}
    	int ans=0;
    	for(int i=0;i<=r-l;i++)
    		ans+=!st[i];
    	cout<<ans;
    	return 0;
    }
    

    再来一道类似的题:https://www.acwing.com/problem/content/198/

  • 相关阅读:
    G. Reducing Delivery Cost 思维+最短路
    Bounding Wall 线段树 + 思维 ccpc 2020 秦皇岛 B
    Java代理模式
    Java开发 使用反射判断一个类的是否继承指定接口类
    Java开发 AES加解密工具类——兼容Android9.0
    Java byte转换工具类
    注册LiveData或者MutableLiveData的观察者导致的内存泄露问题
    Android开发 NavOptions记录
    关于MySQL的命名规范
    Locust学习笔记(5)
  • 原文地址:https://www.cnblogs.com/neflibata/p/12871758.html
Copyright © 2011-2022 走看看