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

题意:

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

知识补充:

  • 因数枚举:分解一个数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;
}

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

时间: 2024-10-12 07:10:01

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

区间内素数的个数

2016.1.26 试题描述 给定两个正整数 a 和 b,请你统计区间 [a,b) 内有多少个素数. 输入 共一行包含两个正整数 a 和 b,用一个空格分隔开. 输出 一个数,表示所给区间内的素数的个数. 输入示例 22 37 输出示例 3  其他说明 数据范围:1≤ a < b ≤ 10^12 , b-a ≤ 10^7 .样例说明:有23. 29 和 31 共 3 个素数. 区间筛嘛~随便筛~就是当年写的代码比较难看?_? #include<iostream> #include<

挑战程序设计竞赛 P131 区间DP

书上好多题没补 PS.整个DP是根据Q来划分的,dalao的代码就是不一样啊 #include<bits/stdc++.h> #define rep(i,j,k) for(int i=j;i<=k;i++) #define oo 0x3f3f3f3f using namespace std; const int maxn = 233; int A[maxn],P,Q; int dp[maxn][maxn]; int main(){ ios::sync_with_stdio(0); int

区间内素数的个数(也要用到埃氏算法)

题目大意:给定正整数a和b,请问区间[a,b)内有多少个素数 限制条件:a<b<=10^12    b-a<=10^6 样例: 22 37 3 22801763489 22801787297 1000 思路:由于b以内的合数的最小质因数一定不超过根号b,所以如果有根号b以内的素数表的话,就可以用埃氏算法运用在[a,b)上了.  也就是说,先分别做好[2,根号b)的表和[a,b)的表, 然后从[2,根号b)的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是[a,b)以内

吉比特_笔试_区间内素数个数

import java.util.Scanner; /** 输入M.N,1 < M < N < 1000000,求区间[M,N]内的所有素数的个数.素数定义:除了1以外,只能被1和自己整除的自然数称为素数 输入描述: 两个整数M,N 输出描述: 区间内素数的个数 示例1 输入 2 10 输出 4 * @author zhaoz * */ public class getMtoNPrime { public static void getPrimeCount(int m, int n) {

[转] AOJ 0525 Osenbei《挑战程序设计竞赛(第2版)》练习题答案

来自 码农场 ? AOJ 0525 Osenbei<挑战程序设计竞赛(第2版)>练习题答案 只把代码复制过来,原博的其他分析请看链接. 1 #include <iostream> 2 #include <bitset> 3 #include <algorithm> 4 5 using namespace std; 6 7 bitset<10000> cookie[10]; 8 9 ///////////////////////////SubMai

poj2431 Expedition (优先队列) 挑战程序设计竞赛

题目链接:http://poj.org/problem?id=2431 Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9148   Accepted: 2673 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor driver

《挑战程序设计竞赛》课后练习题解集——3.4 熟练掌握动态规划

<挑战程序设计竞赛>课后练习题解集——3.4 熟练掌握动态规划 状态压缩DP POJ 2441  有N头牛,M个槽,N,M≤20,每头牛只在指定的pi个槽里进食,不与其他牛共享槽.问有多少种分配方案. dp[i][S],当前第i头牛要进食,槽的使用状态为S 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 using namespace std; 5 6 int n, m; 7 in

POJ 3420 Quad Tiling 题解 《挑战程序设计竞赛》

POJ 3420 Quad Tiling贴瓷砖:4*N的地板上用2*1的瓷砖铺满,求所有方案数对M求余.3.4熟练掌握动态规划矩阵的幂久违地上了节课,太无聊,只好刷一题.假设S[n]表示填满n时的方案数,有S[0]=1.定义矩阵M[p][q] := 边缘p和边缘q可以拼合时取1,否则取0所谓的可以拼合表示,两个边缘拼起来后长度为1(为2就拼接不起来了),且内部缝隙可以用2*1的瓷砖填满.那么M就有一些简单的性质了,比如M的第一行应该是:0 0 0 0 0 0... 继续阅读:码农场 » POJ

POJ 3411 Paid Roads 题解 《挑战程序设计竞赛》

POJ 3411 Paid Roads开路:N个城市间有m条单向路,分别从a到b,可以在c处交P路费,也可以直接交R路费.那么问题来了,你的挖掘机怎么开最省钱?3.4熟练掌握动态规划状态压缩DP乍一看可以Dijkstra,实际上的确可以Dijkstra.不过多了一个预交费的c,所以在遍历的时候多了一维状态,这个维度储存当前走过的城市集合.在Dijkstra的时候,如果走过了c那么就有两个选择,选其中最省的即可:否则没得选.#include <iostream> #include&nb.