POJ3292 Semi-prime H-numbers

时间:2023-12-17 13:42:08

传送门:

刷《数论一本通》时看到的题,简单记录一下。

题目大意(照抄书上的):形如4n+1的数被称为H数,乘法在H数组成的集合内是封闭的。在这个集合中是能被1和本身整除的数叫H-素数,其余的数被称为H合数,1个

H-合成数是一个能且只能被分解成两个H-素数乘积的H合数,求0-h内有多少个H合成数。

题解:

首先,两个H素数的乘积一定是H数,这个可以推导出来:

POJ3292 Semi-prime H-numbers

所以只要我们求出0-h内有多少个H素数,就可以得到本题的答案。根据同余原理我们知道如果i是素数,那么i(5+4x)必定不是H素数且一定是H数,那么就可以通过筛发求出本题的答案。

 //POJ 3292
 //by Cydiater
 //2016.8.29
 #include <iostream>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <string>
 #include <iomanip>
 #include <ctime>
 #include <cmath>
 #include <queue>
 #include <map>
 #include <algorithm>
 using namespace std;
 #define ll long long
 #define up(i,j,n)       for(int i=j;i<=n;i++)
 #define down(i,j,n)     for(int i=j;i>=n;i--)
 ;
 ;
 const int oo=0x3f3f3f3f;
 inline int read(){
       ,f=;
       ;ch=getchar();}
       +ch-';ch=getchar();}
       return x*f;
 }
 ,N;
 namespace solution{
       void pret(){
             memset(prime,,sizeof(prime));
             memset(semi,,sizeof(semi));
             memset(ans,,sizeof(ans));
             ;i<=LIM;i+=){
                   if(prime[i])continue;
                   Count[++cnt]=i;
                   ;i*(*j+)<=LIM;j++)prime[i*(*j+)]=;
             }
             up(i,,cnt)up(j,,i)if(Count[i]*Count[j]>LIM)break;
             ;
             up(i,,LIM)ans[i]=ans[i-]+semi[i];
       }
       void slove(){
             )printf("%d %d\n",N,ans[N]);
       }
 }
 int main(){
       //freopen("input.in","r",stdin);
       using namespace solution;
       pret();
       slove();
       ;
 }