大意
求 L L L到 R R R的区间质数个数+可以被两个质数的乘积表示的数的个数
思路
欧式筛,中途顺便判断可以被两个质数的乘积表示的数
代码
#include<cstdio>
using namespace std;long long dsg[10000001]={};
int j,n,a[100001],b[100001],m,zs[1000001],lenz;
bool vis[10000001],vis2[10000001];
inline int read()
{
char c;int f=0,d=1;
while(c=getchar(),c<48||c>57)if(c=='-')d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),c>47&&c<58) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void write(long long x){if(x>9)write(x/10);putchar(x%10+48);return;}
signed main()
{
m=read();
for(register int i=1;i<=m;i++) a[i]=read(),b[i]=read(),n=b[i]>n?b[i]:n;
vis[1]=vis[0]=true;
for(register int i=2;i*i<=n;i++)
if(!vis[i]) for(int j=i;i*j<=n;j++) vis[i*j]=true;//vis表示是否是合数
for(register int i=2;i*i<=n;i++)
if(!vis[i]) for(int j=i;i*j<=n;j++) if(!vis[j]) vis2[i*j]=true;//vis2表示是否能被两个质数表出
for(register int i=2;i<=n;i++) dsg[i]=dsg[i-1]+(vis2[i]|!vis[i]);//前缀和
for(register int i=1;i<=m;i++) write(dsg[b[i]]-dsg[a[i]-1]),putchar(10);//输出
}