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!

  • 相关阅读:
    POJ 3140 Contestants Division (树dp)
    POJ 3107 Godfather (树重心)
    POJ 1655 Balancing Act (树的重心)
    HDU 3534 Tree (经典树形dp)
    HDU 1561 The more, The Better (树形dp)
    HDU 1011 Starship Troopers (树dp)
    Light oj 1085
    Light oj 1013
    Light oj 1134
    FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
  • 原文地址:https://www.cnblogs.com/wangshengjun/p/sushuX.html
Copyright © 2011-2022 走看看