using
System;
class
GFG{
public
int
MAX = 1000;
static
bool
isArmstrong(
int
x)
{
int
n = x.ToString().Length;
int
sum1 = 0;
int
temp = x;
while
(temp > 0)
{
int
digit = temp % 10;
sum1 += (
int
)Math.Pow(digit, n);
temp /= 10;
}
if
(sum1 == x)
return
true
;
return
false
;
}
static
int
getMid(
int
s,
int
e)
{
return
s + (e - s) / 2;
}
static
int
queryArmstrongUtil(
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
queryArmstrongUtil(st, ss, mid, qs, qe,
2 * index + 1) +
queryArmstrongUtil(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)
{
if
(i < 0 || i > n - 1)
{
Console.Write(
"Invalid Input"
);
return
;
}
int
diff = 0, oldValue = 0;
oldValue = arr[i];
arr[i] = new_val;
if
(isArmstrong(oldValue) &&
isArmstrong(new_val))
return
;
if
(!isArmstrong(oldValue) &&
!isArmstrong(new_val))
return
;
if
(isArmstrong(oldValue) &&
!isArmstrong(new_val))
{
diff = -1;
}
if
(!isArmstrong(oldValue) &&
!isArmstrong(new_val))
{
diff = 1;
}
updateValueUtil(st, 0, n - 1, i, diff, 0);
}
static
void
queryArmstrong(
int
[] st,
int
n,
int
qs,
int
qe)
{
int
ArmstrongInRange = queryArmstrongUtil(
st, 0, n - 1, qs, qe, 0);
Console.WriteLine(
"Number of Armstrong numbers "
+
"in subarray from "
+ qs +
" to "
+
qe +
" = "
+ ArmstrongInRange);
}
static
int
constructSTUtil(
int
[] arr,
int
ss,
int
se,
int
[] st,
int
si)
{
if
(ss == se)
{
if
(isArmstrong(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) +
constructSTUtil(arr, mid + 1, se,
st, si * 2 + 2);
return
st[si];
}
static
int
[] constructST(
int
[] arr,
int
n)
{
int
x = (
int
)(Math.Ceiling(Math.Log(n, 2)));
int
max_size = 2 * (
int
)Math.Pow(2, x) - 1;
int
[] st =
new
int
[max_size];
constructSTUtil(arr, 0, n - 1, st, 0);
return
st;
}
public
static
void
Main(
string
[] args)
{
int
[] arr = { 18, 153, 8, 9, 14, 5 };
int
n = arr.Length;
int
[] st = constructST(arr, n);
int
start = 0;
int
end = 4;
queryArmstrong(st, n, start, end);
int
i = 3;
int
x = 11;
updateValue(arr, st, n, i, x);
Console.Write(
"Array after update: "
);
for
(
int
j = 0; j < n; j++)
Console.Write(arr[j] +
", "
);
Console.WriteLine();
start = 0;
end = 4;
queryArmstrong(st, n, start, end);
}
}