Skip to content

Commit cd13114

Browse files
Create LIS on Tree Explanation.txt
1 parent a26b85c commit cd13114

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
Sometimes when we are unable to solve a problem on a tree, we should ask ourselves how to solve it on an array.
2+
3+
There is a DP way to solve this on an array where f(i) is the number of ways
4+
5+
-----
6+
7+
Let us first discuss how to find LIS on an array
8+
9+
We will maintain a DP where f(i) is the minimum element that can end a sequence of length i.
10+
11+
f(i) = oo, if there is no sequence of length i possible.
12+
13+
While processing a new element x, we will look for the first i, such that f(i) >= i and then set f(i) = x
14+
15+
We can do this with binary search to find the LIS in O(N log N)
16+
17+
-----
18+
19+
We will ensure that at each point in time, only those vertices are considered which are on the path from 1 to V.
20+
21+
When we enter a vertex, we will push it into the stack and when we leave it in DFS, we will remove it on the stack.
22+
23+
We have to be able to undo our change to the DP array when we leave a vertex.
24+
In order to do this, we need to keep track of it's previous states.
25+
26+
We can do this by making dp(i) a stack rather than a single integer.
27+
When we leave a vertex, we simply pop it from the best dp position for vertex v
28+
29+
We have to modify the binary searches to function over an array of stacks rather than an array of integers
30+
31+
-----
32+
33+
int find_first_greater(int n)
34+
{
35+
int left = 0, right = MAX_N - 1;
36+
37+
//L < x <= R
38+
while(right - left > 1)
39+
{
40+
int mid = (left + right)/2;
41+
42+
if(minimum_ending_of_length[mid].size() == 0 || minimum_ending_of_length[mid].top() >= n)
43+
{
44+
right = mid;
45+
}
46+
else
47+
{
48+
left = mid;
49+
}
50+
}
51+
52+
return right;
53+
}
54+
55+
int find_LIS()
56+
{
57+
int left = 0, right = MAX_N - 1;
58+
59+
//L <= x < R
60+
while(right - left > 1)
61+
{
62+
int mid = (left + right)/2;
63+
64+
if(minimum_ending_of_length[mid].size() > 0)
65+
{
66+
left = mid;
67+
}
68+
else
69+
{
70+
right = mid;
71+
}
72+
}
73+
74+
return left;
75+
}
76+
77+
void dfs(int v, int parent_v)
78+
{
79+
int best_position = find_first_greater(A[v]);
80+
minimum_ending_of_length[best_position].push(A[v]);
81+
82+
LIS_here[v] = find_LIS();
83+
84+
for(int child_v : tree[v])
85+
{
86+
if(child_v == parent_v)
87+
{
88+
continue;
89+
}
90+
91+
dfs(child_v, v);
92+
}
93+
94+
minimum_ending_of_length[best_position].pop();
95+
}
96+
97+
int main()
98+
{
99+
int no_of_vertices;
100+
cin >> no_of_vertices;
101+
102+
for(int i = 1; i <= no_of_vertices; i++)
103+
{
104+
cin >> A[i];
105+
}
106+
107+
int no_of_edges = no_of_vertices - 1;
108+
for(int i = 1; i <= no_of_edges; i++)
109+
{
110+
int u, v;
111+
cin >> u >> v;
112+
113+
tree[u].push_back(v);
114+
tree[v].push_back(u);
115+
}
116+
117+
dfs(1, 0);
118+
119+
for(int v = 1; v <= no_of_vertices; v++)
120+
{
121+
cout << LIS_here[v] << "\n";
122+
}
123+
124+
return 0;
125+
}

0 commit comments

Comments
 (0)