Блог пользователя NeverSpot

Автор NeverSpot, история, 5 часов назад, По-английски

Hey Red Coders,

Recently, I have been trying to solve all the problems in the CSES tree section, but even after trying many things, I have failed to solve the last two problems. After searching for solutions, I learned that they can be solved using Centroid Decomposition.

I read some blogs and watched videos on YouTube, but I still can’t grasp the logic. Although I could pretend to understand it and copy paste code to complete the CSES section, I genuinely want to learn and understand why and how it works so that I will be able to solve questions based on it in the future.

I would greatly appreciate it if anyone is willing to explain it to me and help build my intuition around it.

Resources I have tried( although they are really great, but due to my limited knowledge I am not able to grasp the logic):

USACO guide Centroid section

Blog by Tanuj Khattar

Video by Colin Galen

Video by Gaurav Sen

  • Проголосовать: нравится
  • +10
  • Проголосовать: не нравится

»
4 часа назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

It's very hard to explain because we don't know what it is that you are missing — it's hard to write a tutorial here in the comments that's better than all the attempts you've linked. Do you have problems understanding what a centroid decomposition is or are you having difficulty applying it. Maybe you can point out the first sentence in a tutorial of your choice that you don't understand?

Although I could pretend to understand it and simply code to complete the CSES section

This statement is surprising to me — it's usually not completely clear how to apply centroid decomposition, even if you know that it solves the problem.

  • »
    »
    4 часа назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    In Tanuj Khattar's blog point number 3 says:

    Consider any two arbitrary vertices A and B, and the path between them (in the original tree) can be broken down into A–>C and C–>B, where C is the LCA of A and B in the centroid tree.

    But if we take a=2 and b=6, then their lca in the centroid tree will be 2 itself so 2—>2 and 2->6 point is if we are making 5 as a child, not an ancestor of, then how will propagation will work, and will it not miss to update 5... And one doubt I have is which is related to this if we have a bamboo tree of size 10^5, then we apply centroid decomposition, then many ancestors will become a children of their Child then how will we solve for subtree if your subtree does not contain all original elements of subtree...

    I think I should replace the word "simply" with "copy-pasting"

    • »
      »
      »
      107 минут назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится

      then how will propagation will work, and will it not miss to update 5

      What do you mean by "propagation", or "updating 5"?

      Yes, the centroid decomposition of a tree may be totally different from the original tree. Descendants can become ancestors and so on. You cannot rely on anything like that holding in the new tree. What you do know is:

      • any path $$$u \to v$$$ in the original tree visits the LCA of $$$u$$$ and $$$v$$$ in the new tree;
      • the height of the new tree is $$$O(\log n)$$$.

      If you want to apply centroid decomposition, you must find a way to make use of those facts to somehow speed up your solution. This is kinda what I tried to say earlier too. Solving a problem with centroid decmposition is not simply a matter of copying the code of centroid decomposition: you have to figure out a way to use this decomposition.

      I have two new questions:

      1. Did you look the example solutions that Tanuj Khattar gives at the end of the blog?
      2. Is there a specific problem you are trying to solve using centroid decomposition?
      • »
        »
        »
        »
        69 минут назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Thank you very much for your detailed explanation, even though my question was not well structured.

        I now understand that, even though the child-parent relationships are messed up in the new tree, any path from u to v in the original tree will certainly pass through the LCA(v,u) in the new tree because at the point two gets separated is the point of time when LCA(u,v) is removed from original tree Obviously, the height is logN.

        To answer your question:
        1. I did see the example solution for the first problem (E. Xenia and Tree), but I didn’t understand why it works.
        2. As I mentioned in my post, I was trying to solve the last two problems in the CSES tree section.

        1. Fixed-Length Paths 1

        2. Fixed-Length Paths 2

        I am truly amazed that a legendary Red Coder is willing to help, even though my question wasn't well structured. I am very grateful for your effort; it means a lot to me.

        • »
          »
          »
          »
          »
          2 минуты назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          I can try explaining Fixed-Length Paths 1. The pseudocode for it looks like this.

          0 for every vertex u in the centroid tree:
          1     map<int, int> count_dist
          2     for every child v of u in the centroid tree:
          3         for every descendant w of v in the centroid tree:
          4             dist = distance between u and w in the original tree
          5             ans += count_dist[K - dist]
          6 
          7         for every descendant w of v in the centroid tree:
          8            dist = distance between u and w in the original tree
          9            count_dist[dist] += 1
          

          First, complexity is $$$O(n \log^2 n)$$$ (it may be possible to remove one of the logs). Why is that the complexity? For every vertex $$$u$$$ in the centroid tree, you go over all of its descendants in the centroid tree. Conversely, this takes the same amount of time as going over each ancestor of each vertex. Every vertex has at most $$$\log n$$$ ancestors, so this takes $$$O(n \log n)$$$ work at most. The second log comes from using map and computing distances, both of which you may be able to get rid of.

          Why does this work? On line 5, you are essentially adding, for each $$$w$$$, the number of paths with length $$$k$$$, such that the LCA of $$$w$$$ and the vertex at the other end in the centroid tree is $$$u$$$. You want to avoid adding vertex pairs where the LCA is lower in the centroid tree; that's why you go over every child $$$v$$$ of $$$u$$$, as opposed to just iterating over all descendants of $$$u$$$.

»
4 часа назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by NeverSpot (previous revision, new revision, compare).