using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Linq;
class
HelloWorld {
public
static
int
MAX = 1000;
public
static
void
createHash(HashSet<
int
> hash,
int
maxElement)
{
int
prev = 0;
int
curr = 1;
hash.Add(prev);
hash.Add(curr);
while
(curr <= maxElement) {
int
temp = curr + prev;
hash.Add(temp);
prev = curr;
curr = temp;
}
}
public
static
int
getMid(
int
s,
int
e)
{
return
s + ((e - s) / 2);
}
public
static
int
queryFibonacciUtil(List<
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
queryFibonacciUtil(st, ss, mid, qs, qe, 2 * index + 1) +
queryFibonacciUtil(st, mid + 1, se, qs, qe, 2 * index + 2);
}
public
static
void
updateValueUtil(List<
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);
}
}
public
static
void
updateValue(
int
[] arr, List<
int
> st,
int
n,
int
i,
int
new_val,
HashSet<
int
> hash)
{
if
(i < 0 || i > n - 1) {
Console.WriteLine(
"Invalid Input"
);
return
;
}
int
diff = 0;
int
oldValue = 0;
oldValue = arr[i];
arr[i] = new_val;
if
(hash.Contains(oldValue) ==
true
&& hash.Contains(new_val) ==
true
)
return
;
if
(hash.Contains(oldValue) ==
false
&& hash.Contains(new_val) ==
false
)
return
;
if
(hash.Contains(oldValue) ==
true
&& hash.Contains(new_val) ==
false
){
diff = -1;
}
if
(hash.Contains(oldValue) ==
false
&& hash.Contains(new_val) ==
true
){
diff = 1;
}
updateValueUtil(st, 0, n -1, i, diff, 0);
}
public
static
void
queryFibonacci(List<
int
> st,
int
n,
int
qs,
int
qe)
{
int
FibonacciInRange = queryFibonacciUtil(st, 0, n - 1, qs, qe, 0);
Console.WriteLine(
"Number of Fibonacci numbers in subarray from "
+ qs +
" to "
+ qe +
" = "
+ FibonacciInRange);
}
public
static
int
constructSTUtil(
int
[] arr,
int
ss,
int
se,
List<
int
> st,
int
si,
HashSet<
int
> hash)
{
if
(ss == se) {
if
(hash.Contains(arr[ss]) ==
true
)
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, hash) +
constructSTUtil(arr, mid + 1, se, st, si * 2 + 2, hash);
return
st[si];
}
public
static
List<
int
> constructST(
int
[] arr,
int
n, HashSet<
int
> hash)
{
int
x = Convert.ToInt32((Math.Ceiling(Math.Log(n)*2.303)));
int
max_size = 2 * Convert.ToInt32(Math.Pow(2, x)) - 1;
List<
int
> st =
new
List<
int
>();
for
(
int
i = 0; i < max_size; i++){
st.Add(0);
}
constructSTUtil(arr, 0, n - 1, st, 0, hash);
return
st;
}
static
void
Main() {
int
[] arr = { 1, 2, 3, 4, 8, 9 };
int
n = arr.Length;
int
maxEle = 0;
for
(
int
j = 0; j < n; j++){
maxEle = Math.Max(maxEle, arr[j]);
}
HashSet<
int
> hash =
new
HashSet<
int
>();
createHash(hash, maxEle);
List<
int
> st = constructST(arr, n, hash);
int
start = 0;
int
end = 4;
queryFibonacci(st, n, start, end);
int
i = 3;
int
x = 5;
updateValue(arr, st, n, i, x, hash);
start = 0;
end = 4;
queryFibonacci(st, n, start, end);
}
}