zoukankan      html  css  js  c++  java
  • 小X的质数

    题目描述:

                在小X的认知里,质数是除了本身和1以外,没有其他因数的数。

          但由于小 X对质数的热爱超乎寻常,所以小X同样喜欢那些虽然不是质数, 但却是由两个质数相乘得来的数。

             于是,我们定义一个数小 X喜欢的数,当且仅其是一个质数或是两个质数的乘积。

    输入格式:

                第一行输入个正整数 Q,表示询问的组数。
             接下来 Q行,包含两个正整数 L和 R,保证 L≤R(1<=L<=R<=10000000)。

    输出格式:

                输出 Q行 ,每一个整数,表示该区间范围内小 X喜欢的数的个数。

    样例输入 

        1

        1 6

    样例输出 

        5

    解题思路:

          这道题目的数据非常的大,到了1千万!所以,用普通的筛表法+后来要查询时用到的q*二个二分查找肯定是超时的。所以我们要用厉害一点的筛——线性筛。

           线性筛其实是个模板。i从2循环到1千万,如果当前的在数组f中i这个位置标记为0的话,则i为素数,将数组f中i这个位置赋为i,并将i放入数组p中。判断如果当前f[i]==i||f[i/f[i]]==i/f[i],则用前缀和sum[i]=sum[i-1]+1,否则sum[i]=sum[i-1]。再来一重循环j,从1到j<=p数组中数的个数&&p[j]<=f[i],当i*p[j]在1千万以内时,则f[i*p[j]]=p[j]。  

          用线性筛,筛的时候用O(n),而到查询时则用q*O(1),所以总时间复杂度为O(n+q),这样就不用怕超时了。

    代码:(请不要直接拷贝哦) 

    1 #include <cstdio> 

    2 #define maxn 10000005 

    3 int f[maxn],p[4000000],sum[maxn],t; 

    4 using namespace std;

     5 int main()
     6 {
     7   int q;
     8   scanf("%d",&q);
     9   for (int i=2;i<=maxn;i++)//线性筛
    10   {
    11     if (!f[i])
    12     {
    13       f[i]=i;
    14       p[++t]=i;
    15     }
    16     if ((f[i]==i)||(f[i/f[i]]==i/f[i])) sum[i]=1;
    17       sum[i]+=sum[i-1];
    18     for (int j=1;j<=t&&p[j]<=f[i];j++)
    19     {
    20       if (i*p[j]>maxn) break;
    21       f[i*p[j]]=p[j];
    22     }
    23   }
    24   for (int i=1;i<=q;i++)
    25   {
    26      int x,y;
    27      scanf("%d%d",&x,&y);
    28      printf("%d
    ",sum[y]-sum[x-1]);
    29   }
    return 0;
    30 }

    OVER!

  • 相关阅读:
    更改ubuntu的官方镜像源
    python中的decorator的作用
    thunderbird 设置 邮件回复时内容在上方显示
    Sapnco3 RfcTable Structure
    DbEntry 访问Access2010数据库
    DbEntry 默认 主键ID为long
    DbEntry 简单实现
    nginx学习时使用EditPuls编辑conf.xml
    java的集合类面试题
    tomcat组成介绍和调优方案
  • 原文地址:https://www.cnblogs.com/wangshengjun/p/sushuX.html
Copyright © 2011-2022 走看看