• [模板] 区间筛素数


    原理:一个数的倍数肯定不是素数

    若给定子区间[fst, lst]

    则必有区间内任意数最大的因子是sqrt(lst);

    因此只需要将2 - sqrt(lst)中的所有质数的倍数从区间[fst, lst]中划掉即可

    剩下的就是区间内的素数

    注意两个情况

    1. 第一次筛出的素数就在区间里 要特判

    2. 将区间[fst, lst]映射入[0, lst - fst]

    3.bitset优化


    例题 https://www.acwing.com/problem/content/198/

    代码:

    /*
        Zeolim - An AC a day keeps the bug away
    */
     
    //pragma GCC optimize(2)
    #include <cstdio>
    #include <iostream>
    #include <bitset>
    #include <cstdlib>
    #include <cmath>
    #include <cctype>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <set>
    #include <sstream>
    #include <map>
    #include <ctime>
    #include <vector>
    #include <fstream>
    #include <list>
    #include <iomanip>
    #include <numeric>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const int INF = 0x3f3f3f3f;
    const int MAXN = 1e6 + 10;
    const ll MOD = 1e9 + 7;
     
    vector <ll> getprime(ll n, ll m)
    {
    	vector <ll> pri;
    	bitset <MAXN> used(0), rused(0);
    	ll len = sqrt(m);
    	for(int i = 2; i <= len; ++i)
    	{
    		if(!used[i])
    		{
    			ll x = i, y = max(x, x * (n / x));
     
    			while(y <= m)
    			{
    				if(y - n >= 0 && y != x)
    					rused[y - n] = true;
    				y += x;
    			}
    			for(int j = 2 * i; j <= len; j += i)
        		{
        			used[j] = true;
        		}
    		}
    	}
    	 
    	for(int i = 0; i <= m - n; ++i)
    	{
    		if(i + n >= 2 && !rused[i])
    			pri.push_back(i + n);
    	}
    	return pri;
    }
     
    int main()
    {
        //ios::sync_with_stdio(false);
        //cin.tie(0);     cout.tie(0);
        //freopen("D://test.in", "r", stdin);
        //freopen("D://test.out", "w", stdout);
     
    	ll n, m;
     
    	while(scanf("%lld%lld", &n, &m) != EOF)
    	{
    		getprime(n, m);
    	
    		vector <ll> rpri = getprime(n, m);
    	
    		int cha = -1, pa = -1, pb = -1;
    	
    		int rcha = INF, rpa = -1, rpb = -1;
    	
    		for(int i = 1; i < rpri.size(); ++i)
    		{
    			int val = rpri[i] - rpri[i - 1];
    			if(val > cha)
    			{
    				cha = val, pa = rpri[i - 1], pb = rpri[i];
    			}
    			if(val < rcha)
    			{
    				rcha = val, rpa = rpri[i - 1], rpb = rpri[i];
    			}
    		}
    		
    		if(cha > 0)
    			printf("%d,%d are closest, %d,%d are most distant.
    ", rpa, rpb, pa, pb);
    		else
    			printf("There are no adjacent primes.
    ");
    	}
     
    	
     
        return 0;
    }
    
  • 相关阅读:
    C#中IEnumerable、ICollection、IList、List之间的区别
    H5中画图标签Canvas---画矩形,画线,画圆,渐变色,图形载入
    centos启用ftp功能
    CentOS 7 安装FTP服务器(vsftpd)
    Linux下如何修改用户默认目录
    Centos搭建FTP服务器
    MyBatis 示例之存储过程
    MyBatis:MyBatis操作MySQL存储过程
    mybatis的select、insert、update、delete语句
    日常运维中的相关日志切割处理方法总结 [Logrotate、python、shell脚本实现 ]
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270379.html
Copyright © 2020-2023  润新知