• 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
    ");
     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
    ");
     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
    ",num[l[i]]);
     97             }
     98             else
     99             printf("%d
    ",sum[rr]-sum[ll-1]);
    100         }
    101     }
    102      return 0;
    103 }
    View Code
  • 相关阅读:
    UVALive
    训练指南 UVA
    训练指南 UVALive
    Codeforces Round #535 (Div. 3)
    训练指南 UVALive
    训练指南 UVALive
    Codeforces Round #534 (Div. 2)
    Codeforces Round #532 (Div. 2)
    《算法问题实战策略》——chaper9——动态规划法技巧
    《训练指南》——8.3
  • 原文地址:https://www.cnblogs.com/fanminghui/p/4241506.html
Copyright © 2020-2023  润新知