刷《数论一本通》时看到的题,简单记录一下。
题目大意(照抄书上的):形如4n+1的数被称为H数,乘法在H数组成的集合内是封闭的。在这个集合中是能被1和本身整除的数叫H-素数,其余的数被称为H合数,1个
H-合成数是一个能且只能被分解成两个H-素数乘积的H合数,求0-h内有多少个H合成数。
题解:
首先,两个H素数的乘积一定是H数,这个可以推导出来:
所以只要我们求出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(); ; }