区间素数筛

题目描述

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 prime-factor prime because the number of prime factors of 210=2×3×5×7 is 4, which is a composite number.

In this problem, you are given an integer interval [l,r]. Your task is to write a program which counts the number of prime-factor prime numbers in the interval, i.e. the number of prime-factor prime numbers between l and r, inclusive.

输入

The input consists of a single test case formatted as follows.

l r
A line contains two integers l and r (1≤l≤r≤109), which presents an integer interval [l,r]. You can assume that 0≤r−l<1,000,000.

输出

Print the number of prime-factor prime numbers in [l,r].

样例输入

复制样例数据

1 9

样例输出

4
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int prime[maxn],v[40005],cnt,num[maxn],str[maxn];//num是保存因子个数,str是lr区间里面的数
int vis[38]= {0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1};//判断因子个数是否素数
void getp(int n)//得到sqrt(r)内的素数,线性筛
{
    for(register int i=2; i<=n; ++i)
    {
        if(v[i]==0)
            v[i]=i,prime[++cnt]=i;
        for(register int j=1; j<=cnt; ++j)
        {
            if(prime[j]>v[i]||prime[j]>n/i)
                break;
            v[i*prime[j]]=prime[j];
        }
    }
}
int main()
{
    int l,r,templ,tempr,poi;
    scanf("%d %d",&l,&r);
    int len=r-l+1;
    getp(sqrt(r));
    for(register int i=l; i<=r; ++i)//赋值
        str[i-l+1]=i;
    for(register int j=1; j<=cnt; ++j)//对sqrt(r)内的素数进行枚举
    {
        templ=ceil(l/(prime[j]*1.0));//i的左区间边际
        tempr=floor(r/(1.0*prime[j]));//i的右区间边际
        for(register int i=templ; i<=tempr; ++i)//枚举i
        {
            poi=i*prime[j]-l+1;
            if(poi>len)continue;
            while(str[poi]%prime[j]==0)//除去因子
                str[poi]=str[poi]/prime[j],++num[poi];
        }
    }
    int ans=0;
    for(register int i=1; i<=len; ++i)//当str[i]还不为1时说明质因子个数还得加1,因为不为1的数肯定剩下的是素数
        if((str[i]==1&&vis[num[i]])||(str[i]!=1&&vis[num[i]+1]))++ans;
    printf("%d\n",ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/lengsong/p/11386228.html

时间: 2024-11-09 19:21:47

区间素数筛的相关文章

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<

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

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 angr

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

Help Hanzo (素数筛+区间枚举)

Help Hanzo 题意:求a~b间素数个数(1 ≤ a ≤ b < 231, b - a ≤ 100000).     (全题在文末) 题解: a~b枚举必定TLE,普通打表MLE,真是头疼.. b - a ≤ 100000 是关键. 类似素数筛的方法: 1.初始化vis[]=0 ; 2.素数的倍数vis[]=1; 3.  b较小时,素数筛解决   b很大时,素数筛的vis[]会MLE,此时用vis2[i-a]保存vis[i]就不会MLE 了.. #include<iostream>