Halo :D!
Story: It was 4AM and i was unable to sleep so i brought you a nice trick and couple of problems to practice it.
Introduction
(Our dp changes if we change root of the tree, otherwise it wont make any sens to use this trick)
Lets say we want to find $$$dp_v$$$ for every vertex in a tree, this dp must be updated using the children of vertex $$$v$$$. Then the trick allows you to move the root from a vertex to one of it's adjacent vertices in $$$O(1)$$$.
It will be much better if the problem wants you to move the root to all vertices and find maximum of dp-s or etc.
Implementation
First calculate dp for a root $$$rat$$$. Its obvious that if we change root $$$r$$$ to one of its adjacent vertex $$$v$$$, then only $$$dp_r$$$ and $$$dp_v$$$ can change, so that we can update $$$dp_r$$$ using its new children and past $$$dp_r$$$, also $$$dp_v$$$ can be updated the same way.
Note: Don't iterate over $$$r$$$ and $$$v$$$ children, it will be $$$O(\sum\limits_v\binom{d_v}{2})$$$ if you do it and $$$W(n^2)$$$ so just don't.($$$d_v$$$ is the degree of vertex $$$v$$$)
Now being able to move the root with distance one, we will run a dfs from $$$rat$$$, and move the root with dfs.
See the semi-code below, i hope it helps for better understanding:
Problems
I cant open atcoder so there is no solution for the problems from atcoder, sorry.
Problem5//no solution right now
Probelm6//no solution right now
Please comment the problems which can be solved using this trick.
Advanced
Lets say that the problem has queries, such that each query gives two vertices $$$r$$$ and $$$v$$$ and wants you to calculate $$$f(r, v)$$$, its equal to $$$dp_v$$$ when the root is $$$r$$$. It can be solved with rerooting + LCA, it will need additional $$$O(n)$$$ memory and answers each query in $$$O(Q*(L+log_2n))$$$ time(our LCA answers each query in $$$O(L)$$$ time).
So lets see how it works, for every edge($$$v$$$ \to $$$u$$$) find $$$dp_v$$$ if the root is $$$u$$$ and $$$dp_u$$$ if the root is $$$v$$$, also for every vertex $$$v$$$ find $$$dp_v$$$ if $$$v$$$ is the root, it will take the time it takes to move the root around and an additional $$$O(n)$$$ memory at all. Then if the query is in form $$$v$$$ and $$$v$$$(i.e. it wants to find $$$dp_v$$$ such that the tree is rooted at vertex $$$v$$$ itself) so we have calculated and just print it, otherwise the problem is reduced to the following problem:
You are given two vertices $$$v$$$ and $$$u$$$$$$(u \ne v)$$$ what is the second vertex in the unique path from $$$v$$$ to $$$u$$$(it means we want to find out which child of $$$v$$$ is the closest to $$$u$$$).
This problem can be solved using LCA(we say the root of the tree is vertex 1 for LCA), find they're LCA, if it wasn't equal to $$$v$$$, then the answer is $$$v$$$'s parent(the root is vertex 1), otherwise move $$$u$$$ using binary lifting until it's depth is equal to $$$v$$$'s depth plus 1, it can be done in $$$O(log_2n)$$$, let the answer to the reduced problem be $$$z$$$, then the answer to the whole query is equal to $$$f(z, v)$$$ such that $$$z$$$ is adjacent to $$$v$$$ we have precalculated this value so just print it :).
See the semi-code below, i skipped known parts so i will use $$$lca(u, v)$$$ for LCA, $$$moveto(v)$$$ to move the root to vertex $$$v$$$, $$$f(r, u)$$$ for $$$dp_u$$$ when the root is $$$r$$$ and $$$rise(u, v)$$$ to find the ancestor of $$$u$$$ whit depth equal to $$$depth_v+1$$$. Sorry for late implementation.
I will make a polygon problem for advanced part as soon as i can.
I hope it will help you with solving DP-Tree problems.
Thanks for your attention.