-
Notifications
You must be signed in to change notification settings - Fork 108
/
Copy pathSegmented Sieve.cpp
77 lines (63 loc) · 1.73 KB
/
Segmented Sieve.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#define MAX 1000010
#define BASE_SQR 216
#define BASE_LEN 10010
#define BASE_MAX 46656
#define chkbit(ar, i) (((ar[(i) >> 6]) & (1 << (((i) >> 1) & 31))))
#define setbit(ar, i) (((ar[(i) >> 6]) |= (1 << (((i) >> 1) & 31))))
int p, primes[BASE_LEN];
unsigned int base[(BASE_MAX >> 6) + 5], isprime[(MAX >> 6) + 5];
void Sieve(){
clr(base);
int i, j, k;
for (i = 3; i < BASE_SQR; i++, i++){
if (!chkbit(base, i)){
k = i << 1;
for (j = (i * i); j < BASE_MAX; j += k){
setbit(base, j);
}
}
}
p = 0;
for (i = 3; i < BASE_MAX; i++, i++){
if (!chkbit(base, i)){
primes[p++] = i;
}
}
}
int SegmentedSieve(long long a, long long b){
long long j, k, x;
int i, d, counter = 0;
if (a <= 2 && 2 <= b) counter = 1; /// 2 is counted separately if in range
if (!(a & 1)) a++;
if (!(b & 1)) b--;
if (a > b) return counter;
clr(isprime);
for (i = 0; i < p; i++){
x = primes[i];
if ((x * x) > b) break;
k = x << 1;
j = x * ((a + x - 1) / x);
if (!(j & 1)) j += x;
else if (j == x) j += k;
while (j <= b){
setbit(isprime, j - a);
j += k;
}
}
/// Other primes in the range except 2 are added here
d = (b - a + 1);
for (i = 0; i < d; i++, i++){
if (!chkbit(isprime, i) && (a + i) != 1) counter++;
}
return counter;
}
int main(){
Sieve();
int T = 0, t, i, j, a, b;
scanf("%d", &t);
while (t--){
scanf("%d %d", &a, &b);
printf("Case %d: %d\n", ++T, SegmentedSieve(a, b));
}
return 0;
}