7

Online Query Based Rerooting Technique

 2 years ago
source link: http://codeforces.com/blog/entry/76150
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Online Query Based Rerooting Technique

Halo :D!

Story: It was 4 AM and I was unable to sleep so I brought you a nice trick and a couple of problems to practice it.

Introduction

(Our DP changes if we change the root of the tree, otherwise it won't make any sense to use this trick)

Let's say we want to find for every vertex in a tree, we must be able to update using the children of vertex . Then the trick allows you to move the root from a vertex to one of its adjacent vertices in .

Implementation

First, calculate DP when the root is some vertex . Its obvious that if we change root to one of its adjacent vertices, , then only and can change, so that we can update using its new children and last , also can be updated the same way. It really depends on the DP.

Note:

Don't iterate over children of vertices when moving the root, it will be and so just don't. ( is the degree of vertex )

Now being able to move the root with distance one, we will run a DFS from , and move the root with DFS.

See the semi-code below, i hope it helps for better understanding:

Semi-code

Problems

I can't open some of the problems so there is no solution for them, sorry.

You can read the same trick here, also the site has some problems.

Problem1 Solution

Problem2

Problem3 Solution

Problem4

Problem5 Solution

Probelm6 Solution

Please comment problems that can be solved using this trick.

Advanced

Let's say that the problem has online queries, such that each query gives two vertices and and wants you to calculate , it's equal to when the root is . It can be solved with rerooting + ancestors binary lifting, it will answers each query in time( for binary lifting), and also precalculation.

So lets see how it works, for every edge() find if the root is and if the root is , it will take time and memory, and also for each vertex , store . Then if the query is in form and (i.e. it wants to find such that the tree is rooted at vertex itself) then the answer will be , which is calculated in advance, otherwise the problem is reduced to the following problem:

You are given two vertices and what is the second vertex in the unique path from to (it means we want to find out which vertex is adjacent to and is the closest to ).

This problem can be solved using binary lifting, if is not an ancestor of , then the answer is 's parent(the root is vertex ), otherwise, move using binary lifting until it's depth is equal to 's depth plus 1, it can be done in , let the answer to the reduced problem be , then the answer to the whole query is equal to such that is adjacent to , we have already calculated it.

See the semi-code below, i skipped some parts so i will use to move the root from to , for when the root is and to find the ancestor of with depth equal to in .

Semi-code

I tried to add a problem from polygon for the advanced part, the problem is completed but I couldn't bring it to Codeforces, but I give you the link for problem's package, it includes 50 tests, validator and checker, main correct solution and problem statement, you can try running them in polygon.

Windows Package(50 MB) Linux Package(45 MB)

Here is the complete implementation for the topic, is the size of the subtree of here.

Solution

I used map to store the data, so the solution is a little slower than expected.

I hope it will help you with solving DP-Tree problems.

Thanks for your attention.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK