using
System;
class
Program {
static
int
compare((
int
,
int
)p1, (
int
,
int
)p2)
{
if
(p1.Item1 == p2.Item1)
return
p1.Item2 > p2.Item2 ? 1 : -1;
return
p1.Item1 < p2.Item1 ? -1 : 1;
}
static
void
BuildTree(
int
[] tree,
int
pos,
int
low,
int
high,
int
index,
int
value)
{
if
(index < low || index > high)
return
;
if
(low == high) {
tree[pos] = value;
return
;
}
int
mid = (high + low) / 2;
BuildTree(tree, 2 * pos + 1, low, mid, index,
value);
BuildTree(tree, 2 * pos + 2, mid + 1, high, index,
value);
tree[pos] = Math.Max(tree[2 * pos + 1],
tree[2 * pos + 2]);
}
static
int
FindMax(
int
[] tree,
int
pos,
int
low,
int
high,
int
start,
int
end)
{
if
(low >= start && high <= end)
return
tree[pos];
if
(start > high || end < low)
return
0;
int
mid = (high + low) / 2;
return
Math.Max(FindMax(tree, 2 * pos + 1, low, mid,
start, end),
FindMax(tree, 2 * pos + 2, mid + 1,
high, start, end));
}
static
int
FindLIS(
int
[] arr,
int
n)
{
(
int
,
int
)[] p =
new
(
int
,
int
)[n];
for
(
int
i = 0; i < n; i++) {
p[i] = (arr[i], i);
}
Array.Sort(p, compare);
int
len = (
int
)Math.Pow(
2, Math.Ceiling(Math.Sqrt(n)) + 1)
- 1;
int
[] tree =
new
int
[len];
Array.Fill(tree, 0);
for
(
int
i = 0; i < n; i++) {
BuildTree(
tree, 0, 0, n - 1, p[i].Item2,
FindMax(tree, 0, 0, n - 1, 0, p[i].Item2)
+ 1);
}
return
tree[0];
}
static
void
Main(
string
[] args)
{
int
[] arr = { 10, 22, 9, 33, 21, 50, 41, 60 };
int
n = arr.Length;
Console.WriteLine(
"Length of the LIS: "
+ FindLIS(arr, n));
}
}