public
class
Main
{
static
int
MAX =
1000
;
static
void
sieveOfEratosthenes(
boolean
[] isPrime)
{
isPrime[
1
] =
true
;
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
queryCompositesUtil(
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
queryCompositesUtil(st, ss, mid, qs, qe,
2
* index +
1
)
+ queryCompositesUtil(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.print(
"Invalid Input"
);
return
;
}
int
diff =
0
, 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
queryComposites(
int
[] st,
int
n,
int
qs,
int
qe)
{
int
compositesInRange = queryCompositesUtil(st,
0
, n -
1
, qs, qe,
0
);
System.out.println(
"Number of Composites in subarray from "
+ qs
+
" to "
+ qe +
" = "
+ compositesInRange);
}
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
,
12
,
3
,
5
,
17
,
9
};
int
n = arr.length;
boolean
[] isPrime =
new
boolean
[MAX +
1
];
for
(
int
a =
0
; a < MAX +
1
; a++)
{
isPrime[a] =
true
;
}
sieveOfEratosthenes(isPrime);
int
[] st = constructST(arr, n, isPrime);
int
start =
0
;
int
end =
4
;
queryComposites(st, n, start, end);
int
i =
3
;
int
x =
6
;
updateValue(arr, st, n, i, x, isPrime);
start =
0
;
end =
4
;
queryComposites(st, n, start, end);
}
}