Almost prime numbers are the non-prime numbers which are divisible by only a single prime number.
In this problem your job is to write a program which finds out the number of almost prime numbers
within a certain range.
Input
First line of the input file contains an integer N (N ≤ 600) which indicates how many sets of inputs
are there. Each of the next N lines make a single set of input. Each set contains two integer numbers
low and high (0 < low ≤ high < 1012).
Output
For each line of input except the first line you should produce one line of output. This line contains
a single integer, which indicates how many almost prime numbers are within the range (inclusive)
low … high.
Sample Input
3
1 10
1 20
1 5
Sample Output
3
4
1


【分析】
先打出来sqrt(n)以内的素数表,然后对于每个素数x,他对答案的贡献就是最大的p使x^p<=n,即log(x,n)。注意精度误差。
用1..r的减去1..l-1的就是答案。


【代码】

//
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=1e6;
int pri[mxn+5],vis[mxn+5];
int tot;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void shai()
{
int i,j;
fo(i,2,mxn)
{
if(!vis[i]) pri[++tot]=i;
fo(j,1,tot)
{
if(i*pri[j]>=mxn) break;
vis[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
}
inline ll query(ll x)
{
ll i,j,ans=0;
double k=log(x+0.1);
for(i=1;i<=tot && pri[i]*pri[i]<=x;i++)
ans+=k/log(pri[i])-1;
return ans;
}
int main()
{
int i,j,t;
shai();
ll l,r;
t=read();
while(t--)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",query(r)-query(l-1));
}
return 0;
}