Round #226 (Div. 2) C、 Bear and Prime Numbers

1、题目链接:http://codeforces.com/contest/385/problem/C

2、昨天A、B两题都1Y了,剩下一个半小时就在发呆。。。要是不能突破第三题我就只能永远在DIV2混了。。。

3、刚开始觉得困难是因为L,R最多达到2*10^9,觉得筛法求素数的话数组开不了那么大,后来我发现我SB了,因为x最多10的7次方,素数总不可能超过x的最大值吧?等我反应过来的时候,比赛已经快结束了。。。

4、学会了计算空间的方法,以前看到256MB,512MB之类的都没什么概念,导致了10000000的数组都不敢开。。。没问题的,尽情开吧,本题最多可开60000000!

5、还有一个犯SB的地方就是——面对一个从小到大排好序的数组,居然挨个查找!充分体现了我的蒟蒻本质。。。应该二分查找。。。

6、我的思路也不对,刚开始是每读入一个数把它的因子都分解出来,加到f上,其实这样重复算了很多,而且算了很多不必要的数(比如合数),正确方法是用类似计数排序的方法把那些数装进数组num中,然后用类似筛法求素数的方法统计出每个因子有多少个数符合。。。“知道素数后判断是否是某数的因子”总比“知道某数后找出它有哪些因子”要容易许多。。。

7、本题是道好题啊~以后有比赛就参加吧,时间赶不上就参加virtual contest。比赛是最能发现问题的。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,num[10000010]={0},prime[670000],vis[10000010]={0},sum[670000]={0},f[670000]={0};
void sieve(int n){
    int m=(int)sqrt(n+0.5);
 memset(vis,0,sizeof(vis));
 for(int i=2;i<=m;i++)
  for(int j=i*i;j<=n;j+=i) vis[j]=1;
}
int gen_primes(int n){
        sieve(n);
 int c=0;
 for(int i=2;i<=n;i++) if(!vis[i])
  prime[c++]=i;
 return c;
}
int main(){
    int temp,N,m,L,R,max=0;
 scanf("%d",&N);
 for(int i=0;i<N;i++){
  scanf("%d",&temp);
  if(temp>max) max=temp;
                num[temp]++;
 }
 int cnt=gen_primes(10000000);
        for(int i=0;i<cnt;i++){
     for(int j=prime[i];j<=max;j+=prime[i]){
      f[i]+=num[j];
            }
            if(i==0) sum[0]=f[0];
            else sum[i]=sum[i-1]+f[i];
 }
 scanf("%d",&m);
 int jL,jR;
 for(int i=0;i<m;i++){
     scanf("%d%d",&L,&R);
  jL=lower_bound(prime,prime+cnt,L)-prime;
  jR=upper_bound(prime,prime+cnt,R)-prime-1;
  printf("%d\n",jL>=1?sum[jR]-sum[jL-1]:sum[jR]);
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值