cf C Bear and Prime Numbers

题意:给你一个n,输入n个数,然后输入m,接下来有m个询问,每一个询问为[l,r],然后输出在区间内[l,r]内f(p)的和,p为[l,r]的素数,f(p)的含义为在n个数中是p的倍数的个数。

思路:先打出10000000内的素数,然后统计每一个素数在n个数中的倍数的个数记录在num[i]中,在每次询问的是找出l,r在素数表的位置,然后计算就可以。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #define maxn 10000100
  5 using namespace std;
  6 
  7 int n,m,cnt;
  8 int x[maxn];
  9 bool vis[maxn];
 10 int vis1[maxn];
 11 int f[maxn];
 12 int l[maxn],r[maxn];
 13 int num[maxn];
 14 int sum[maxn];
 15 
 16 void Getprime()
 17 {
 18     cnt=0;
 19     vis[0]=vis[1]=true;
 20     memset(vis,false,sizeof(vis));
 21     for(int i=2; i<=maxn; i++)
 22     {
 23         if(!vis[i])
 24         {
 25             f[cnt++]=i;
 26             for(int j=2*i; j<=maxn; j+=i)
 27             {
 28                 vis[j]=true;
 29             }
 30         }
 31     }
 32 }
 33 
 34 int main()
 35 {
 36     Getprime();
 37     while(scanf("%d",&n)!=EOF)
 38     {
 39         memset(vis1,0,sizeof(vis1));
 40         int max1=0;
 41         for(int i=0; i<n; i++)
 42         {
 43             scanf("%d",&x[i]);
 44             vis1[x[i]]++;
 45             max1=max(max1,x[i]);
 46         }
 47         for(int i=0; i<cnt; i++)
 48         {
 49             for(int j=f[i]; j<=max1; j+=f[i])
 50             {
 51                  if(vis1[j])
 52                  {
 53                      num[f[i]]+=vis1[j];
 54                  }
 55             }
 56         }
 57         memset(sum,0,sizeof(sum));
 58         for(int i=0; i<cnt; i++)
 59         {
 60             if(i==0)
 61             {
 62                 sum[i]=num[f[i]];
 63             }
 64             else
 65             {
 66                 sum[i]=sum[i-1]+num[f[i]];
 67             }
 68 
 69         }
 70         scanf("%d",&m);
 71         for(int i=1; i<=m; i++)
 72         {
 73             scanf("%d%d",&l[i],&r[i]);
 74             if(l[i]>10000000)
 75             {
 76                 printf("0\n");
 77                 continue;
 78             }
 79             int ll=lower_bound(f,f+cnt,l[i])-f;
 80             int rr=lower_bound(f,f+cnt,r[i])-f;
 81             if(f[cnt-1]<=r[i])
 82             {
 83                 rr=cnt-1;
 84             }
 85             if(f[ll]>r[i])
 86             {
 87                 printf("0\n");
 88                 continue;
 89             }
 90             if(f[rr]>r[i])
 91             {
 92                rr=rr-1;
 93             }
 94             if(l[i]==r[i])
 95             {
 96                 printf("%d\n",num[l[i]]);
 97             }
 98             else
 99             printf("%d\n",sum[rr]-sum[ll-1]);
100         }
101     }
102      return 0;
103 }
View Code

 

posted @ 2015-01-22 13:58  null1019  阅读(194)  评论(0编辑  收藏  举报