using
System;
class
Program {
static
int
INT_MAX = 2147483647;
static
int
INT_MIN = -2147483648;
class
segment {
public
int
l;
public
int
sl;
public
segment(
int
l,
int
sl)
{
this
.l = l;
this
.sl = sl;
}
}
static
segment query(segment[] tree,
int
index,
int
s,
int
e,
int
qs,
int
qe)
{
segment res =
new
segment(0, 0);
res.l = -1;
res.sl = -1;
if
(qs > e || qe < s || s > e) {
return
res;
}
if
(s >= qs && e <= qe) {
return
tree[index];
}
int
mid = (s + e) / 2;
segment left
= query(tree, 2 * index, s, mid, qs, qe);
segment right = query(tree, 2 * index + 1, mid + 1,
e, qs, qe);
int
largest = Math.Max(left.l, right.l);
int
second_largest
= Math.Min(Math.Max(left.l, right.sl),
Math.Max(right.l, left.sl));
res.l = largest;
res.sl = second_largest;
return
res;
}
static
void
update(segment[] tree,
int
index,
int
s,
int
e,
int
i,
int
val)
{
if
(i < s || i > e) {
return
;
}
if
(s == e) {
tree[index].l = val;
tree[index].sl = INT_MIN;
return
;
}
int
mid = (s + e) / 2;
update(tree, 2 * index, s, mid, i, val);
update(tree, 2 * index + 1, mid + 1, e, i, val);
tree[index].l = Math.Max(tree[2 * index].l,
tree[2 * index + 1].l);
tree[index].sl
= Math.Min(Math.Max(tree[2 * index].l,
tree[2 * index + 1].sl),
Math.Max(tree[2 * index + 1].l,
tree[2 * index].sl));
}
static
void
buildtree(segment[] tree,
int
[] a,
int
index,
int
s,
int
e)
{
if
(s > e) {
return
;
}
if
(s == e) {
tree[index].l = a[s];
tree[index].sl = INT_MIN;
return
;
}
int
mid = (s + e) / 2;
buildtree(tree, a, 2 * index, s, mid);
buildtree(tree, a, 2 * index + 1, mid + 1, e);
int
largest = Math.Max(tree[2 * index].l,
tree[2 * index + 1].l);
int
second_largest
= Math.Min(Math.Max(tree[2 * index].l,
tree[2 * index + 1].sl),
Math.Max(tree[2 * index + 1].l,
tree[2 * index].sl));
tree[index].l = largest;
tree[index].sl = second_largest;
}
static
void
Main(
string
[] args)
{
int
n = 5;
int
[] a = { 1, 3, 4, 2, 5 };
segment[] tree =
new
segment[4 * n + 1];
for
(
int
i = 0; i < 4 * n + 1; i++) {
tree[i] =
new
segment(0, 0);
}
buildtree(tree, a, 1, 0, n - 1);
segment res = query(tree, 1, 0, n - 1, 0, 2);
Console.WriteLine(
"Maximum product in the range 0 and 2 before update: "
+ (res.l * res.sl));
update(tree, 1, 0, n - 1, 1, 6);
res = query(tree, 1, 0, n - 1, 0, 2);
Console.WriteLine(
"Maximum product in the range 0 and 2 after update: "
+ (res.l * res.sl));
}
}