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 <iostream>
#include <string>
#include <vector>
#define rep(i,j,k) for(int i=(j); i<k; i++)
#define maxn 100100
#define maxm 50010
#define max 20000000
int a[maxn];
int l[maxm],r[maxm];
long long int res[maxm];
long long b[max];
using namespace std;
int n,m;
int f(int t){
int times = 0;
if(a[1]%t == 0)
times++;
for(int i=2; i<=n; ++i){
if(t>i && t%i==0)
return 0;
if(a[i]%t == 0)
times++;
}
return times;
}
int main(void){
while(cin >> n){
rep(i,1,n+1)
cin >> a[i];
cin >> m;
rep(i,0,m)
cin >> l[i] >> r[i];
for(int i=2; i<max; ++i)
b[i]=f(i);
for(int i=0; i<m; i++){
for(int j=l[i]; j<=r[i]; ++j)
res[i] += b[j];
cout << res[i] << endl;
}
}
return 0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int kMaxX = 10000000, kMaxP = 664579;
int n, pr[kMaxP + 1];
bool not_pr[kMaxX + 1];//非素数
int sum[kMaxX + 1];
void init(){
for(int i=2; i<=kMaxX; ++i){
if(!not_pr[i]) pr[++pr[0]] = i;
//找出所有的素数,存入pr数组中,pr[0]表示当前素数个数
for(int j=1,k; j<=pr[0] && (k=pr[j]*i)<=kMaxX; ++ j){
not_pr[k] = true;
//每个素数的倍数都是非素数,这样可以省去很多判断的时间
if(i%pr[j]==0) break;
}
}
}
int main(void){
init();
scanf("%d", &n);
for(int x; n--; ){
scanf("%d", &x);
for(int i=1; pr[i]*pr[i]<= x; ++i)//用pr[i]*pr[i]<=n降低时间复杂度
if(x%pr[i]==0){
++sum[pr[i]];
while(x%pr[i]==0)
x /= pr[i];
//意在把x变小
}
if(x != 1)
//例如x刚开始等于14,在上面的for循环中
//只能找到14%2==0,不能找到14%7==0,使用while循环加判断则可以做到
++sum[x];
}
for(int i=3; i<=kMaxX; ++ i)
sum[i]+=sum[i-1];
//sum[i]对应r[i]的f()函数加权和
scanf("%d", &n);
for(int l,r; n--; ){
scanf("%d%d", &l, &r);
l = min(l, kMaxX);//为什么???
r = min(r, kMaxX);//因为对x[]数组,最大只有10,000,000
//当l r大于kMaxX时不可能存在x满足条件
printf("%d\n", sum[r]-sum[l-1]);
}
return 0;
}