• 小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!

  • 相关阅读:
    常用颜色
    在VS2010中打开VS2012的项目
    vs2012 断点不能调试
    Setup Factory 打包.netframework 2.0
    Access 中数据库操作时提示from子句语法错误
    vs2012 .netFramwork2.0发布到xp
    c# access插入null值
    Visual Studio安装卸载模板
    Codeforces 455D
    ACdream 1157 (cdq分治)
  • 原文地址:https://www.cnblogs.com/wangshengjun/p/sushuX.html
Copyright © 2020-2023  润新知