import
java.io.*;
import
java.util.*;
class
GFG
{
static
int
MAX =
1000
;
static
void
sieveOfEratosthenes(
boolean
isPrime[])
{
isPrime[
1
] =
false
;
for
(
int
p =
2
; p * p <= MAX; p++)
{
if
(isPrime[p] ==
true
)
{
for
(
int
i = p *
2
; i <= MAX; i += p)
isPrime[i] =
false
;
}
}
}
static
int
getMid(
int
s,
int
e) {
return
s + (e - s) /
2
; }
static
int
queryPrimesUtil(
int
[] st,
int
ss,
int
se,
int
qs,
int
qe,
int
index)
{
if
(qs <= ss && qe >= se)
return
st[index];
if
(se < qs || ss > qe)
return
0
;
int
mid = getMid(ss, se);
return
queryPrimesUtil(st, ss, mid, qs, qe,
2
* index +
1
) +
queryPrimesUtil(st, mid +
1
, se, qs, qe,
2
* index +
2
);
}
static
void
updateValueUtil(
int
[] st,
int
ss,
int
se,
int
i,
int
diff,
int
si)
{
if
(i < ss || i > se)
return
;
st[si] = st[si] + diff;
if
(se != ss) {
int
mid = getMid(ss, se);
updateValueUtil(st, ss, mid, i, diff,
2
* si +
1
);
updateValueUtil(st, mid +
1
, se, i, diff,
2
* si +
2
);
}
}
static
void
updateValue(
int
arr[],
int
[] st,
int
n,
int
i,
int
new_val,
boolean
isPrime[])
{
if
(i <
0
|| i > n -
1
) {
System.out.println(
"Invalid Input"
);
return
;
}
int
diff =
0
;
int
oldValue;
oldValue = arr[i];
arr[i] = new_val;
if
(isPrime[oldValue] && isPrime[new_val])
return
;
if
((!isPrime[oldValue]) && (!isPrime[new_val]))
return
;
if
(isPrime[oldValue] && !isPrime[new_val])
{
diff = -
1
;
}
if
(!isPrime[oldValue] && isPrime[new_val])
{
diff =
1
;
}
updateValueUtil(st,
0
, n -
1
, i, diff,
0
);
}
static
void
queryPrimes(
int
[] st,
int
n,
int
qs,
int
qe)
{
int
primesInRange = queryPrimesUtil(st,
0
, n -
1
, qs, qe,
0
);
System.out.println(
"Number of Primes in subarray from "
+
qs +
" to "
+ qe +
" = "
+ primesInRange);
}
static
int
constructSTUtil(
int
arr[],
int
ss,
int
se,
int
[] st,
int
si,
boolean
isPrime[])
{
if
(ss == se) {
if
(isPrime[arr[ss]])
st[si] =
1
;
else
st[si] =
0
;
return
st[si];
}
int
mid = getMid(ss, se);
st[si] = constructSTUtil(arr, ss, mid, st, si *
2
+
1
, isPrime) +
constructSTUtil(arr, mid +
1
, se, st, si *
2
+
2
, isPrime);
return
st[si];
}
static
int
[] constructST(
int
arr[],
int
n,
boolean
isPrime[])
{
int
x = (
int
)(Math.ceil(Math.log(n)/Math.log(
2
)));
int
max_size =
2
* (
int
)Math.pow(
2
, x) -
1
;
int
[] st =
new
int
[max_size];
constructSTUtil(arr,
0
, n -
1
, st,
0
, isPrime);
return
st;
}
public
static
void
main (String[] args)
{
int
arr[] = {
1
,
2
,
3
,
5
,
7
,
9
};
int
n = arr.length;
boolean
[] isPrime =
new
boolean
[MAX +
1
];
Arrays.fill(isPrime, Boolean.TRUE);
sieveOfEratosthenes(isPrime);
int
[] st = constructST(arr, n, isPrime);
int
start =
0
;
int
end =
4
;
queryPrimes(st, n, start, end);
int
i =
3
;
int
x =
6
;
updateValue(arr, st, n, i, x, isPrime);
start =
0
;
end =
4
;
queryPrimes(st, n, start, end);
}
}