LightOJ 1197(区间素数筛)

Help Hanzo

Amakusa, the evil spiritual leader has captured the beautiful princess Nakururu. The reason behind this is he had a little problem with Hanzo Hattori, the best ninja and the love of Nakururu. After hearing the news Hanzo got extremely angry. But he is clever and smart, so, he kept himself cool and made a plan to face Amakusa.

Before reaching Amakusa‘s castle, Hanzo has to pass some territories. The territories are numbered as a, a+1, a+2, a+3 ... b. But not all the territories are safe for Hanzo because there can be other fighters waiting for him. Actually he is not afraid of them, but as he is facing Amakusa, he has to save his stamina as much as possible.

He calculated that the territories which are primes are safe for him. Now given a and b he needs to know how many territories are safe for him. But he is busy with other plans, so he hired you to solve this small problem!

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case contains a line containing two integers a and b (1 ≤ a ≤ b < 231, b - a ≤ 100000).

Output

For each case, print the case number and the number of safe territories.

Sample Input

3

2 36

3 73

3 11

Sample Output

Case 1: 11

Case 2: 20

Case 3: 4

Note

A number is said to be prime if it is
divisible by exactly two different integers. So, first few primes are 2,
3, 5, 7, 11, 13, 17, ...

分析:b最大为2^31-1,但闭区间[a,b]范围比较小,因此可以先筛出2^16次方的素数,

因为小于b的合数必有小于√b 的素因子,可以简单证明一下,假设合数x<b,x有素因子k>√b,

那么x/k<√b,即x/k必有小于√b 的素因子。

#include<cstdio>
#include<cstring>
int p[46342],cnt=1;
int c[46342];
void prime()
{
    for(int i=4;i<46342;i+=2) c[i]=1;
    p[0]=2;
    for(int i=3;i<46342;i++)
    {
        if(!c[i])
        {
            p[cnt++]=i;
            for(int j=i+i;j<46342;j+=i)
            c[j]=1;
        }
    }
}

int s[100011];
int main()
{
    int T;
    int cas=0;long long a,b;
    scanf("%d",&T);
    prime();
    while(T--)
    {
        scanf("%lld%lld",&a,&b);
        memset(s,0,sizeof(s));
        //把合数筛出来
        for(int i=0;i<cnt&&p[i]*p[i]<=b;i++)
        {
            long long k=a/p[i];
            long long temp=k*p[i];
            if(temp<a) temp+=p[i];
            if(temp==p[i]) temp+=p[i];
            while(temp<=b)
            {
                s[temp-a]++;
                temp+=p[i];
            }
        }
        int ans=0;
        for(int i=0;i<=b-a;i++)
        if(!s[i]) ans++;
        if(a<=1) ans--;//1不是素数
        printf("Case %d: %d\n",++cas,ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/ACRykl/p/8654098.html

时间: 2024-10-07 10:29:39

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

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

区间素数筛模版

区间素数筛模版 筛出区间[a,b]的素数.(b-a<=10000,1<=a<=b<=2^31) 存在P中,素数个数即为P的size(). ll a,b; bool isprime[maxn]; vector<ll> prime; bool isP[maxn]; vector<ll> P; void play_prime() { memset(isprime,1,sizeof(isprime)); isprime[1]=0; for(int i=2;i<

区间素数筛

题目描述 A positive integer is called a "prime-factor prime" when the number of its prime factors is prime. For example, 12 is a prime-factor prime because the number of prime factors of 12=2×2×3 is 3, which is prime. On the other hand, 210 is not a

poj 2689 区间素数筛

The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousands of years is the question of primality. A prime number is a number that is has no prop

lightoj1197区间素数筛

模板题,不过好像有点问题,当a==1的时候,答案把一也算进去了,要减去 #include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib

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

埃氏筛法(素数筛)

埃式筛法:给定一个正整数n(n<=10^6),问n以内有多少个素数? 做法:做法其实很简单,首先将2到n范围内的整数写下来,其中2是最小的素数.将表中所有的2的倍数划去,表中剩下的最小的数字就是3,他不能被更小的数整除,所以3是素数.再将表中所有的3的倍数划去……以此类推,如果表中剩余的最小的数是m,那么m就是素数.然后将表中所有m的倍数划去,像这样反复操作,就能依次枚举n以内的素数,这样的时间复杂度是O(nloglogn). 题解:如果要是按照一个一个判断是否是素数然后把ans+1,时间复杂度

浅谈线性素数筛

素数筛的用处还是蛮多的,有很多和素数有关的题都要用到素数筛,所以有一个高效的筛法自然是非常好的吖,普通筛法(暴力筛法)就不说了,因为有了高效的也没人在会用普通筛法了吧. 线性素数筛是用每一个合数的最小的质因数筛掉它,所以时间复杂度保证是线性的. 模板:https://www.luogu.org/problemnew/show/P3383 代码: 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int

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