poj 3292 Semi-prime H-numbers
#include <iostream> //线性筛+树状数组
#include<stdio.h>
using namespace std;
#define Max 1000010
int n,table[Max],vis[Max],prime[80000];
int lowbit(int x)
{
return x&(-x);
}
void modify(int x)
{
if(vis[x]==0)
{
vis[x]=1;
while(x<Max)
{
table[x]++;
x+=lowbit(x);
}
}
}
int getsum(int x)
{
int s=0;
while(x>0)
{
s+=table[x];
x-=lowbit(x);
}
return s;
}
int main()
{
int curr=9,rear=1;
prime[1]=5;
while(curr<Max/5) //上界是Max/5
{
int tag=1;
for(int j=1;prime[j]*prime[j]<=curr;++j)
{
if(curr%prime[j]==0)
{
tag=0;break;
}
}
if(tag==1)
prime[++rear]=curr;
curr+=4;
}
for(int i=1;prime[i]*prime[i]<Max;++i)
for(int j=i;j<=rear&&prime[i]*prime[j]<Max;++j) //要添加j<=rear,因为当j的下标超过rear后,prime[j]=0,那么将无限循环下去
{
modify(prime[i]*prime[j]);
}
while(scanf("%d",&n),n)
{
printf("%d %d\n",n,getsum(n));
}
return 0;
}