MODDI's blog

By MODDI, history, 21 month(s) ago, In English

I came across this problem while practicing, but I didn't solve it, some suggestions for these types of problems would be appreciated. We have a tree with n nodes(n <= 300000), and each node has a number A(1 <= A <= 10^9). The first line of the input consists of two numbers n and A0 (the number of nodes and the number on node 1). Each of the next n-1 lines has two numbers Ai and the parent of node i. For every node except the root, we need to find the number of nodes that have a strictly smaller number than the current node. Then we need to update every node on the path from the current node to the root, set Aj = max(Aj, Ai)

Example:
5 400
350 0
300 1
450 2
420 0
550 3
Answer:
0
0
3
0
4
  • Vote: I like it
  • +7
  • Vote: I do not like it

»
21 month(s) ago, # |
  Vote: I like it 0 Vote: I do not like it

Can you provide me with the original statement or link to the problem?

  • »
    »
    21 month(s) ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Its from a national competition, the language is different.

»
21 month(s) ago, # |
  Vote: I like it 0 Vote: I do not like it

Have you tried heavy-light decomposition? If you are updating some node, you will update everything up to some point on path to root. If there are k intervals of different numbers, you need to change, it will be done in something like O(log^2n + klogn) (sequence on any path to root will be ascending so we will always change some consistent interval on path). But if there are k intervals of different numbers, then they were produced by some earlier updates. Tho we have n updates, and one can produce at most logn new intervals on path to root (there are at most logn light edges on path to root). I'm not 100% sure if it works, i can try solve it and let you know if it does. Could you provide link to original statement?

  • »
    »
    21 month(s) ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Well, this is the first time I'm hearing about heavy-light decomposition, I'll do some research on the topic, and try to learn it.

    Here's the link https://mendo.mk/Task.do?id=809, although I belive you will need to create an account to be able to submit the problem.

    • »
      »
      »
      20 months ago, # ^ |
      Rev. 2   Vote: I like it 0 Vote: I do not like it

      I thought that you need to tell how many smaller nodes are in the whole tree, not only on path to root. This way it's simple, standard hld. If you're intrested i got ac by this code

      Code
      • »
        »
        »
        »
        20 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Can you tell me what the dfs functions do?

        And what do we store in roz(the size of the subtree?)

        In the segment tree, we store maximum and minimum to answer queries for some range, correct?

        • »
          »
          »
          »
          »
          20 months ago, # ^ |
          Rev. 6   Vote: I like it 0 Vote: I do not like it

          dfss are to build hld structure.
          Theses tables are:

          roz — size of subtree
          p — parent of node
          s — leader of our heavy path going up (up most node on that path)
          (by heavy path, i mean path consisting only heavy edges)
          pre — pre order of node

          In second dfs (pre_dfs) we're calculating pre_order, but we're visiting our child's in particular order. We visit our heaviest child first, and then the rest. This way all heavy paths are consistent intervals by their pre order. We also calculate paths leaders.

          Doing it this way allow us to use single segment tree on all pre_orders and do updates/queries on its sub segments (we got all heavy path's on single segment tree).

          Segment tree indeed stores maximum, minimum, and updates are, "set some vale on interval". If some path has maximum < val then we know we can take whole path and jump to parent of leader. If maximum >= val then we know there's no point in searching up for smaller numbers, so we just query special_query and return our answer.

          Special query just count numbers smaller than val and set's them to val.

          Theses special_query_deliver is needed bcs since we're keeping all heavy-paths on same segtree first we need to find their base-segments(? idk how it's called in eng), and then we can assume these segments are ascending.