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

Автор vamaddur, история, 9 лет назад, По-английски

Problem: http://www.usaco.org/index.php?page=viewproblem2&cpid=102

Another user pointed out to me the similarity between this problem and one on the most recent January contest (http://www.usaco.org/index.php?page=viewproblem2&cpid=696). The latter problem can be solved using the combination of a preorder traversal and BIT.

I was wondering if it is possible to solve the former problem with a combination of a Segment Tree and DFS (closest possible method to a preorder traversal). The segment tree would use lazy propagation to update the range of edges, but I am not sure how to use a DFS in this situation.

Am I on a right track? If so, I would appreciate input on how to continue. If not, please point me to another possible solution.

Please help, and thanks in advance!

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

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

I don't think it is very plausible to solve Grass Planting with a Segment Tree representing the nodes of the tree. In order to a segment tree to actually be useful, you usually want to update a small number of contiguous segments, or else the time complexity will be huge. For the problem in the January contest, the preorder traversal was done to be able to update all the children of a node at once (in one contiguous segment). However in this problem, you need to update paths from one node from another, and I believe it is impossible(at least according to my current knowledge) to maintain an ordering so that you can update all the nodes on the path at once or at least efficiently. Why not Heavy-Light Decomposition? Researching it would be useful in the future.

P.S. Though I think it is unlikely that another solution exists, I would also be very interested if there is a solution other than using Heavy-Light Decomposition.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +13 Проголосовать: не нравится

Addition for a path a — b can be reduced to addition for path root — a. So the value added to edge par(x) — x : sum of all addition for path root — (some node in x's subtree). So the problem can be solved by dfs preorder + bit.

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

    O.O (red coder!!)

    Sorry, I don't really understand some parts of your solution. What is path root? How do we process the addition and queries by using BIT? Could I ask for some more details about your solution? Thanks :D

    • »
      »
      »
      9 лет назад, скрыть # ^ |
      ← Rev. 2  
      Проголосовать: нравится +8 Проголосовать: не нравится

      Say you have a path from A to B. Let L be the LCA of A and B. Notice we add one to the path from the root to A, and one to the path from the root to B. Then, we subtract two from the path from the root to L (it got added twice). Call this "increment A, increment B, decrement L (edit: twice — thanks pacu).

      Now to query an edge, we simply want to know how many values in the subtree of this edge were "incremented" or "decremented". Then we can calculate its value.

»
9 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Thanks for your help everyone (especially @gongy)! I ended up solving the problem with a BIT (as range updates were not actually necessary) and modified DFS.

If anyone would like to see my C++11 solution, PM me. :)