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;
}
}
本文来自博客园,作者:lei_yu,转载请注明原文链接:https://www.cnblogs.com/lytql/p/15015101.html