POJ3292 Semi-prime H-numbers

水是挺水的

我们首先可以直接预处理出所有H-素数,再预处理出所有的H-半素数,最后求得答案即可。

对于H-素数,使用欧拉筛即可,稍微改一下,只枚举4x+1即可。

对于H-半素数,直接$O(n\sqrt n)$暴力判断即可

时间复杂度$O(n\sqrt n)$

代码如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,prime[1000001],b[1000001],t[1000001],cnt,q,f[1000001],g[1000001];
int main()
{
	for(int i=1;i<=1000000;i++)
	{
		t[i]=t[i-1];
		if((i-1)%4==0)t[i]++;
	}
	for(int i=2;i<=1000000;i++)
	{
		if((i-1)%4)continue;
		if(!b[i])prime[++cnt]=i;
		for(int j=1;j<=cnt&&i*prime[j]<=1000000;j++)
		{
			b[i*prime[j]]=1;
			if(i%prime[j]==0)break;
		}
	}
	for(int i=1;i<=1000000;i+=4)
	{
		if(i==1)continue;
		for(int j=1;j<=int(sqrt((float)i));j+=4)
		{
			if(j==1)continue;
			if(i%j==0&&!b[j]&&!b[(i/j)])
			{
				g[i]=1;
				break;
			}
		}
		g[i]+=g[i-4];
	}
	while(114514)
	{
		cin>>n;
		if(n==0)return 0;
		cout<<n<<" "<<g[n]<<endl;
	}
}

方法2:

在筛H-素数的时候可以顺便筛出H-半素数。

当i也是素数时,$i*p[j]$即为H-半素数。

时间复杂度:$O(n)$

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,prime[1000001],b[1000001],t[1000001],cnt,q,f[1000001],g[1000001];
int main()
{
	for(int i=1;i<=1000000;i++)
	{
		t[i]=t[i-1];
		if((i-1)%4==0)t[i]++;
	}
	for(int i=2;i<=1000000;i++)
	{
		if((i-1)%4)continue;
		if(!b[i])prime[++cnt]=i;
		for(int j=1;j<=cnt&&i*prime[j]<=1000000;j++)
		{
			b[i*prime[j]]=1;
			if(!b[i])g[i*prime[j]]=1;
			if(i%prime[j]==0)break;
		}
	}
	for(int i=1;i<=1000000;i+=4)
	{
		if(i==1)continue;
		g[i]+=g[i-4];
	}
	while(114514)
	{
		cin>>n;
		if(n==0)return 0;
		cout<<n<<" "<<g[n]<<endl;
	}
}
posted @ 2021-07-15 13:39  lei_yu  阅读(29)  评论(0编辑  收藏  举报