码迷,mamicode.com
首页 > 其他好文 > 详细

《挑战程序设计竞赛》 大区间内素数的个数

时间:2015-07-28 18:41:49      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:

题意:

  • 给一个区间边界值很大的区间,但是区间大小较小,求出该区间内所有质数个数。

知识补充:

  • 因数枚举:分解一个数n,至于要从1 枚举到 n?? 即可,然后把i和 n / i 当做因数加入vector
  • 整数分解(把一个整数枚举出其质数基连乘的形式):从2开始枚举质数基,然后每次把该整数尽可能的被当前质数除去最大次数,这样该整数就会变小,极大减少枚举量。注意和map搭配使用,记录每一个质数的个数。
  • 埃式素数筛法的复杂度是:Ologlogn看做线性也无妨。

  • 求区间[a,b)内素数的个数,由于b的最大质数因子小于b所有先把2到b内的素数打表,再利用素数筛法,筛除[a,b)内所有的合数。

#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;

vector<int> prime;

void get_prime(void) {
    bool isprime[1000009];
    memset(isprime, 0, 1000009);
    for (int i = 2; i <= 1000000; i++) {
        if (!isprime[i]) {
            prime.push_back(i);
            for (int j = i; j <= 1000000; j += i) isprime[j] = true;
        }
    }
}

int primes(LL a, LL b) {
    bool isprime[1000009];
    int ans = 0;
    memset(isprime, 0 , b - a);
    for (int i = 0; i < prime.size() && prime[i] < b; i++) {
        int j = 0;
        bool find = false;
        for (LL k  = a; k < b; k++, j++) if (k % prime[i] == 0) { find = true; break; }
        if (!find) continue;
        for (; j < b - a; j += prime[i]) { isprime[j] = true; if (j + a == prime[i]) ans++; }
    }
    for (int i = 0; i < b - a; i++) if (!isprime[i]) ans++;
    if (a <= 1) ans -= 2 - a;
    return ans;
}

int main(void) {
    //problem: , address:
    LL a, b;
    get_prime();
    while (~(scanf("%lld%lld", &a, &b))) {
        cout << primes(a, b) << endl;
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

《挑战程序设计竞赛》 大区间内素数的个数

标签:

原文地址:http://blog.csdn.net/jibancanyang/article/details/47108025

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!