Semi-prime H-numbers UVA - 11105 区间筛

题意:定义了一种H素数,H素数的定义是能够被4整除余数为1,且不能写成两个不是1的H数的乘积,然后给定一个n值,问1到n中有多少个能被分解成两个H素数的数。

已经规定1不是h素数了,h数是满足4*n+1的数,所以先预处理出h数,再用筛法将一个h素数的倍数标记掉,同时生成h素数表,之后,枚举两个h素数的乘积,加一个判断大于100001时 break,也就是范围的上限,所以很快,最后递推一下0到i之间存在的h半素数的个数。

#include <iostream>  
#include <cstdio>  
#include <bitset>  
#include <cstring>  
#include <algorithm>  
#include <vector>  
#include <map>  
#include <cmath>  
#include <set>  
#include <queue>  
using namespace std;  
typedef long long ll;    
const int INF=1e9+100;     
const int mod=1e9+7;

const int maxn=1000005;
int t=0;
int b[maxn],d[maxn];
int a[maxn],h[maxn];
void init(){
    for(int i=0;4*i+1<=1000001;i++)
        a[4*i+1]=1;
    int cnt=0;
    for(int i=5;i<=1001001;i++){
        if(a[i]==1){
            h[cnt++]=i;
            for(int j=i*2;j<=1000001;j+=i){
                a[j]=0;
            }
        }
    }
    for(int i=0;i<cnt;i++)
        for(int j=i;j<cnt;j++){
            if(1LL*h[i]*h[j]>1000001) break;
            b[h[i]*h[j]]=1;
        }
    for(int i=1;i<=1000001;i++){
         d[i]=d[i-1];
        if(b[i]==1) d[i]++;
    }
}

int main(){
    //freopen("out.txt","w",stdout);  
    int n;
    init();
    while(scanf("%d",&n)&&n){
        printf("%d %d\n",n,d[n]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值