zoukankan      html  css  js  c++  java
  • 区间素数筛

    题目描述

    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
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    获取设备和 App 信息
    使用 UICollectionView 实现网格化视图效果
    UIImage 读取图片内存优化
    使用 stretchableImageWithLeftCapWidth 方法实现可伸缩图片
    使用 StoryBoard 实现左右按钮切换图片的浏览效果
    二维码图片生成(扩展知识:创建带圆角效果的图片)
    Objective-C语法之扩展(Extension)的使用
    Objective-C语法之字符串NSString去掉前后空格或回车符(可以是NSCharacterSet类型的其它字符)
    Objective-C语法之可变参数
    什么时候layoutSubview会被调用
  • 原文地址:https://www.cnblogs.com/lengsong/p/11386228.html
Copyright © 2011-2022 走看看