POJ 3292 Semi-prime H-numbers 解题报告(筛选)

来源:互联网 发布:网络家长学校 编辑:程序博客网 时间:2024/06/06 04:37

    题目大意:h-number是形如4*n+1的数,如5,9,13。h-number是乘法闭包的。如果一个h-number最多由两个h-number相乘获得,那么它就是H-semi-prime。题目让我们求从1到n的所有H-semi-prime的数量。

    解题报告:直接从1开始筛选就好了,像晒素数一样。注意点细节……代码如下:

#include <cstdio>#include <cstring>#define LL long longconst int maxn=250001;int d[maxn];int sum[maxn];void initial(){    for(int i=1;i<maxn;i++)    {        for(int k=1;k<=i;k++)        {            LL t=(LL)4*i*k+i+k;            if(t>=maxn) break;            if(d[t]<=1)                d[t]=d[i]+d[k]+1;        }    }    for(int i=1;i<maxn;i++)    {        sum[i]=sum[i-1];        if(d[i]==1)            sum[i]++;    }}int main(){    initial();    int n;    while(~scanf("%d",&n) && n)    {        printf("%d %d\n",n,sum[(n-1)/4]);    }}

    所谓的乘法闭包就是说h-number*h-number的结果一定是h-number。很容易证明,(4*n+1)*(4*m+1)=4*(4mn+m+n)+1。所以它是乘法闭包的。