Dual Prime
题目描述
如果一个合数x=p⋅q,p,q是素数且p≠q,我们称x是双素数。 现给你一个区间[a,b],求区间内的的双素数个数。
输入
第一行是一个整数T(1≤T≤30000),为样例的数目。 以后每行一个样例,为两个整数a,b(1≤a≤b≤106)
输出
依次每行输出一个样例的结果。
样例输入
3 1 10 1 100 1 1000000
样例输出
2 30 209867
解题思路:你不是输入两个数a1,b1确定一个区间嘛,所以我就想能不能确定1~a-1这个区间有多少个双素数,1~b这个区间有多少个双素数,最后满足题意的答案即为b[b1]-b[a1-1].
#include<stdio.h>
int a[1000005];//素数
int b[1000005];//dual素数
int main()
{
int i,j;
a[0]=1,a[1]=1;
for(i=2;i*i<=1000000;i++)//筛
{
if(a[i]==0)
{
for(j=2;j*i<=1000000;j++)
{
a[i*j]=1;
}
}
}
a[1]=0;
for(i=2;i*i<=1000000;i++)
{
if(!a[i])//素数之前标记为 0 了,即如果 i 是素数
{
for(j=i+1;i*j<=1000000;j++)// j=i+1 是为了防止 i=j
{
b[j*i]=(!a[j]);//这里太妙了,不必再通过循环将之前的素数标记为 1
}//用a[j]来判断 j 是不是素数,太妙啦!
}
}
// for(i=2;i<=1000000;i++)
// {
// if(a[i]==1)//将合数记为 0
// {
// a[i]=0;
// }
// else
// {
// a[i]=1;
// }
// }
// int sum=0;
// for(i=1;i<=1000000;i++)
// {
// sum+=a[i];
// b[i]=sum;
// }
//printf("%d\n",b[100]);
for(i=2;i<=1000000;i++)
{
b[i]+=b[i-1];//这里就开始计算每一个端点到 1 区间内的双素数个数了
}
int K,a1,b1,n;
scanf("%d",&K);
while(K--)
{
scanf("%d %d",&a1,&b1);
n=b[b1]-b[a1-1]; //这一步处理很巧妙
printf("%d\n",n);
}
}