Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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)

AltStyle によって変換されたページ (->オリジナル) /