LightOJ 1197 Help Hanzo(区间素数筛法)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

#define maxn 50000
int vis[maxn], isprime[5200], num[100005], k;
void prime()//只需要把[1,sqrt(2^31)]之间的素数筛选出来就ok了。
{
    long long i, j;
    for (k=0,i=2; i<maxn; i++)
        if (vis[i] == 0)
        {
            isprime[k ++] = i;
            for (j=i*i; j<maxn; j+=i)
                vis[j] = 1;
        }
    //printf ("%lld\n", k);
}

int main ()
{
    int t, l = 1;
    prime ();
    scanf ("%d", &t);
    while (t --)
    {
        int a, b, ans = 0;
        int n;
        scanf ("%d %d", &a, &b);
        n = b - a;//所求区间最大可达下标
        memset (num, 0, sizeof(num));
        for (int i=0; isprime[i]<=(int)sqrt(b)&& i<k; i++)
        {
            int j = 0;
            if (a % isprime[i] != 0 )//第一个需要筛掉的数(j+a) % isprime[i] == 0
                j = j - a % isprime[i] + isprime[i];
            if (a <= isprime[i])//(j+a) / isprime[i] == 1,则(j+a)是素数,要向下推一个
                j += isprime[i];
            for ( ; j<=n; j+=isprime[i])
            {
                    num[j] = 1;
            }
        }
        for (int i=0; i<=n; i++)//计算素数的数目
            if (!num[i])
            ans ++;
        if (a == 1)//对这种情况特殊处理
            ans --;
        printf ("Case %d: %d\n", l ++, ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Fy1999/p/9732608.html

时间: 2024-10-08 23:52:31

LightOJ 1197 Help Hanzo(区间素数筛法)的相关文章

LightOj 1197 Help Hanzo (区间素数筛选)

题目大意: 给出T个实例,T<=200,给出[a,b]区间,问这个区间里面有多少个素数?(1 ≤ a ≤ b < 231, b - a ≤ 100000) 解题思路: 由于a,b的取值范围比较大,无法把这个区间内的所以素数全部筛选出来,但是b-a这个区间比较小,所以可以用区间素数筛选的办法解决这个题目. 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<

HDU 6069 Counting Divisors(区间素数筛法)

题意:...就题面一句话 思路:比赛一看公式,就想到要用到约数个数定理 约数个数定理就是: 对于一个大于1正整数n可以分解质因数: 则n的正约数的个数就是 对于n^k其实就是每个因子的个数乘了一个K 然后现在就变成了求每个数的每个质因子有多少个,但是比赛的时候只想到sqrt(n)的分解方法,总复杂度爆炸,就一直没过去,然后赛后看官方题解感觉好妙啊! 通过类似素数筛法的方式,把L - R的质因子给分解,就可以在O(nlogn)的时间之内把所以的数给筛出来. 代码: /** @xigua */ #i

LightOJ 1197 Help Hanzo(区间素数筛选)

水题 有t组数据 每组数据有a b 两个数 求a b之间有多少个素数 打表筛选即可 思路:先打一个素数表 找到第一个大于a的素数的倍数j 从j开始筛 筛到b为止 用flag标记 然后筛第二个素数 一直筛到sqrt(b)为止 剩下的就都是素数了 水题 #include <iostream> #include <math.h> #include <stdio.h> #include <string.h> #include <algorithm> #i

区间素数筛法

给定整数a和b,请问区间[a,b)内有多少个素数? a<b<=10^12 b-a<=10^6 因为b以内合数的最小质因数一定不超过sqrt(b),如果有sqrt(b)以内的素数表的话,就可以把筛选法用在[a,b)上了,先分别做好[2,sqrt(b))的表和[a,b)的表,然后从[2,sqrt(b))的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是区间[a,b)内的素数了. 有的时候需要求出某个特定区间的素数,但是数可能很大,数组也开不小,所以需要进行下标偏移,这样才

hdu6069(简单数学+区间素数晒法)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6069 题意: 给出 l, r, k.求:(lambda d(i^k))mod998244353,其中 l <= i <= r, d(i) 为 i 的因子个数. 思路:若 x 分解成质因子乘积的形式为 x = p1^a1 * p2^a2 * ... * pn^an,那么 d(x) = (a1 + 1) * (a2 + 1) * ... * (an + 1) .显然 d(x^k) = (a1 * k

洛谷 P1865 A % B Problem(简单区间素数) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1865 题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对于每次询问输出个数 t,如l或r∉[1,m]输出 Crossing the line 输入输出样例 输入样例#1: 2 5 1 3

LightOJ 1197 LightOJ 1197(大区间素数筛选)

http://lightoj.com/volume_showproblem.php?problem=1197 题目大意: 就是给你一个区间[a,b]让你求这个区间素数的个数 但a.b的值太大没法直接进行素数筛选(没法开那么大的数组),我们可以将a当做0,将b当做b-a 这样求[a,b]之间就变成了求[0, b - a]之间,这样就可以开数组来筛选 下图是代码式子j = j + prime[i] - a % prime[i]的由来 #include<stdio.h> #include<ma

light_oj 1197 区间素数筛

light_oj 1197 区间素数筛 M - Help Hanzo Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice LightOJ 1197 Description Amakusa, the evil spiritual leader has captured the beautiful princess Nakururu. The reason

Light oj 1197 - Help Hanzo (素数筛技巧)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1197 给你a和b求a到b之间的素数个数. 先在小区间素数筛,大区间就用类似素数筛的想法,把a到b之间不是素数的标记出来.因为b-a最多1e5的大小,所以每组数据的时间复杂度最多就o(1e5 log1e5). 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using names