Recently, the bear started studying data structures and faced the following problem.
You are given a sequence of integers x1, x2, ..., xn of
length n and m queries, each of them is characterized
by two integers li, ri.
Let's introduce f(p) to represent the number of such indexes k,
that xk is
divisible by p. The answer to the query li, ri is
the sum:
,
where S(li, ri) is
a set of prime numbers from segment [li, ri] (both
borders are included in the segment).
Help the bear cope with the problem.
The first line contains integer n (1 ≤ n ≤ 106). The second line contains n integers x1, x2, ..., xn (2 ≤ xi ≤ 107). The numbers are not necessarily distinct.
The third line contains integer m (1 ≤ m ≤ 50000). Each of the following m lines contains a pair of space-separated integers, li and ri(2 ≤ li ≤ ri ≤ 2·109) — the numbers that characterize the current query.
Print m integers — the answers to the queries on the order the queries appear in the input.
6 5 5 7 10 14 15 3 2 11 3 12 4 4
9 7 0
7 2 3 5 7 11 4 8 2 8 10 2 123
0 7
Consider the first sample. Overall, the first sample has 3 queries.
- The first query l = 2, r = 11 comes. You need to count f(2) + f(3) + f(5) + f(7) + f(11) = 2 + 1 + 4 + 2 + 0 = 9.
- The second query comes l = 3, r = 12. You need to count f(3) + f(5) + f(7) + f(11) = 1 + 4 + 2 + 0 = 7.
- The third query comes l = 4, r = 4. As this interval has no prime numbers, then the sum equals 0。
#include<cstdio>
#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<cmath>
#define ll __int64
#define MAX 10001009
using namespace std;
int prime[MAX];
ll sum[MAX];
int a[MAX];
int ss[MAX];
void get_prime()
{
prime[0]=prime[1]=1;
memset(prime,0,sizeof(prime));//0为素数
for(int i = 2; i<MAX; i++)
{
sum[i] = sum[i-1];//保留前i个和
if(!prime[i])
{
for(int j = i; j<MAX; j+=i)//加i的倍数的个数,素数的倍数存的是前i个素数被整出的个数和
{
sum[i]+=ss[j];
prime[j] = 1;
}
}
}
}
//2,4,6,8,10
//3, 6,9,12,
//4, 8,12,16
//5,15,20.25
//6, 12,18
int main()
{
int n;
int _max = 0;
memset(sum,0,sizeof(sum));
memset(ss,0,sizeof(ss));
scanf("%d",&n);
for(int i = 1; i<=n; i++)
{
scanf("%d",&a[i]);
ss[a[i]]++;
_max = max(_max,a[i]);
}
// cout<<_max<<endl;
get_prime();
int m;
scanf("%d",&m);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x>_max&&y>_max)//区分界限
{
puts("0");
}
else
{
if(x>_max) x = _max;
if(y>_max) y = _max;
// for(int i = 2;i<=10;i++)
// cout<<sum[i]<<endl;
printf("%I64d\n",sum[y] - sum[x-1]);
}
}
return 0;
}
本文深入探讨了C语言中解决素数筛选问题的高效算法,通过实例展示了如何利用线性写法进行素数筛操作,并详细解析了算法背后的逻辑与应用。文章从输入输出规范入手,逐步引导读者理解并实现该算法,旨在提升编程技巧与解决问题的能力。
300

被折叠的 条评论
为什么被折叠?



