题意:输入两个整数L,U,统计区间[L,U]中有多少个数满足:它本身不是素数,但只有一个素因子。
思路:满足要求的数肯定是一个素数的n次方。先用筛法求出10^6以内的素数,然后枚举n,把满足条件的数存起来。因为区间太大,查找的时候用二分。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include<time.h>
#define INF 1000000
using namespace std;
bool vis[1000010];
long long primes[78500];
vector<long long> ans;
long long find(long long n,int l,int r){
int mid=(l+r)/2;
if(n<ans[0])return 0;
if(n>ans[ans.size()-1]) return ans.size();
if(ans[mid]==n)return mid;
if(l+1==r)return mid+1;
if(n>ans[mid]){
return find(n,mid,r);
}else{
return find(n,l,mid);
}
}
int main(){
memset(vis,0,sizeof(vis));
vis[0]=vis[1]=true;
for(int i=2;i<=1000;i++){
for(int j=i*i;j<=1000000;j+=i){
vis[j]=true;
}
}
int cnt=0;
for(int i=1;i<=1000000;i++){
if(!vis[i])primes[++cnt]=i;
}
for(int i=1;i<=cnt;i++){
long long tmp=primes[i]*primes[i];
while(tmp<=1000000000000LL){
ans.push_back(tmp);
tmp*=primes[i];
}
}
sort(ans.begin(),ans.end());
int t;
cin>>t;
long long L,R;
while(t--){
cin>>L>>R;
int fl=find(L,0,ans.size());
int fr=find(R+1,0,ans.size());
cout<<fr-fl<<endl;
}
return 0;
}