-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathCNTPRIME.cpp
96 lines (96 loc) · 2.76 KB
/
CNTPRIME.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Ivan Carvalho
// Solution to https://www.spoj.com/problems/CNTPRIME/
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e4 + 1;
const int MAXP = 1e6 + 1;
const int MAXS = 1e3 + 1;
int arvore[4 * MAXN], lazy[4 * MAXN], vetor[MAXN], n, m, TC;
int crivo[MAXP];
void build(int pos, int left, int right) {
lazy[pos] = -1;
if (left == right) {
arvore[pos] = !crivo[vetor[left]];
return;
}
int mid = (left + right) / 2;
build(2 * pos, left, mid);
build(2 * pos + 1, mid + 1, right);
arvore[pos] = arvore[2 * pos] + arvore[2 * pos + 1];
}
void update(int pos, int left, int right, int i, int j, int val) {
if (lazy[pos] != -1) {
arvore[pos] = (right - left + 1) * lazy[pos];
if (left != right) {
lazy[2 * pos] = lazy[pos];
lazy[2 * pos + 1] = lazy[pos];
}
lazy[pos] = -1;
}
if (left > right || left > j || right < i) return;
if (left >= i && right <= j) {
arvore[pos] = (right - left + 1) * val;
if (left != right) {
lazy[2 * pos] = val;
lazy[2 * pos + 1] = val;
}
return;
}
int mid = (left + right) / 2;
update(2 * pos, left, mid, i, j, val);
update(2 * pos + 1, mid + 1, right, i, j, val);
arvore[pos] = arvore[2 * pos] + arvore[2 * pos + 1];
}
int query(int pos, int left, int right, int i, int j) {
if (lazy[pos] != -1) {
arvore[pos] = (right - left + 1) * lazy[pos];
if (left != right) {
lazy[2 * pos] = lazy[pos];
lazy[2 * pos + 1] = lazy[pos];
}
lazy[pos] = -1;
}
if (left > right || left > j || right < i) return 0;
if (left >= i && right <= j) {
return arvore[pos];
}
int mid = (left + right) / 2;
return query(2 * pos, left, mid, i, j) +
query(2 * pos + 1, mid + 1, right, i, j);
}
int main() {
crivo[0] = crivo[1] = 1;
for (int i = 2; i < MAXP; i++) {
if (!crivo[i]) {
if (i > MAXS) continue;
for (int j = i * i; j < MAXP; j += i) {
crivo[j] = 1;
}
}
}
scanf("%d", &TC);
for (int tc = 1; tc <= TC; tc++) {
printf("Case %d:\n", tc);
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &vetor[i]);
}
build(1, 1, n);
while (m--) {
int op;
scanf("%d", &op);
if (op == 0) {
int x, y, v;
scanf("%d %d %d", &x, &y, &v);
update(1, 1, n, x, y, !crivo[v]);
} else {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", query(1, 1, n, x, y));
}
}
}
return 0;
}