You are not logged in. Please login at www.codechef.com to post your questions!

×

UPDTREE - editorial

6
2

PROBLEM LINK:

Practice
Contest
Author: Lalit Kundu
Tester: Tasnim Imran Sunny
Editorialist: Devendra Agarwal

DIFFICULTY:

Medium-Hard

PREREQUISITES:

DFS and LCA

PROBLEM:

You have a tree consisting of N vertices numbered 1 to N.
Initially each edge has a value equal to zero. You have to first perform M1 operations and then answer M2 queries.
Operations are defined by:
A B C D: On the path between nodes numbered A and B increase the value of each edge by 1, except for those edges which occur on the path between C and D.
Queries are of the following type:
E F: Print the sum of values of all the edges on the path between two distinct nodes E and F.

Solution:

For solving this problem , we will be solving some sub problems to finally solve this one.
Sub Problem 1
Given 1D array , you need to mantain the array with Update operations of adding X to all index from A to B followed by Query operations of the sum of any subarray.

Solution to Sub Problem 1
Let the array be denoted by Arr[]
For every Update , do Arr[B+1] -= X , Arr[A] += X.
After all Updates , store prefix sum of the Arr[i] at Prefix[i]. It can easily be observed that Prefix Array contains correct numbers at each index.
Store Prefix sum of Prefix Array in Sum[] array.
Now for reporting the sum of array elements from x to y : return Sum[y] - Sum[x-1]

Sub Problem 2
Given 1D array , you need to mantain the array with Update operations of adding 1 to all index from A to B but leaving indexes which are a part of C to D followed by Query operations of the sum of the subarray.

Solution to Sub Problem 2
Essentially the idea here is we would do +X to all elements from A to B and -X to all elements which are in the intersection of the two segments.

We only aim here at finding intersection of two segments.Rest is managed by the logic of problem 1.

Case 1 : If C is more than B then no intersection.
Case 2 : If A is more than D then no intersection.
Case 3 : If A is more than C then common intersection segment is ( A, min(B,D) )
Case 4 : If C is more than A then common intersection segment is ( C, min(B,D) )
Last 2 cases can be merged into 1 as ( max(A,C) , min (B,D) ) is the common intersection if intersection happens.
Removing Cases 1 and 2: if ( max(A,C) > min (B,D) ) then no Intersection

Sub Problem 3
Given a tree, you need to mantain the tree with Update operations of adding X to all Edges in the path from A to B followed by Query operations of the sum of all Edges in the path from E to F.
Solution to Sub Problem 3
Each edge can be mapped to a vertex in the tree.
Can you find the mapping ?
Fix the root. Now consider the edge to be between v1 and v2. Associate the edge to v1 if v2 is the parent of v1 or vice verse.

Path Update from A to B : Let anc be the ancestor of A and B. Add X to Arr[A] and -X to Arr[anc]. Add X to Arr[B] and -X to Arr[anc].
After all update queries , run dfs and Prefix[node] = Arr[node] + Prefix[all_childrens]
Run another Dfs which calculates the sum of all nodes in the path from root to that node and store in that node. Let us denote this array as Sum[]
Report Query: Let anc be the ancestor of E and F. Return Sum[E] + Sum[F] - 2*Sum[anc]
Essentially the idea is that the leaf node is the point our array starts and each path from leaf to root is a 1D array Subproblem because each node has a unique parent.

Are you tired of reading ? Next we come up with the main problem and you will solve it and i will just question you !! Are you ready ?

Main Problem
Refer to Problem above :)
Solution
Given Intersected Segment , can you correctly update the tree ? [ Hint : Sub Problem 2]
Idea for handling intersection is same as Sub problem 2 i.e. we add +X to all nodes in the path from A to B and -X to all nodes in the common Intersection.
We only aim at finding the intersection of two paths , rest is handled by Sub-problem 3.

Let anc1 be the ancestor of A and B. Let anc2 be the ancestor of C and D.
We will deal with all four pairs of disjoint Paths separately i.e [ A anc1 C anc2 ] , [ A anc1 D anc2 ] , [ B anc1 C anc2 ] and [ B anc1 D anc2 ].
Let's us see how to solve any one of them , rest is just a function calling :)

Let us solve [ A anc1 C anc2 ] (Unbiased Choice :) )

Can you find it using sub problem 2?

anc2 must lie in the path from A to anc1 otherwise there will be no intersection [ Reasoning: If there is a intersection and anc2 is not in their path then the intersection must be of a Cross Format but this is not possible because root --> anc1 , root --> anc2 , anc1 --> Cross_Vertex , anc2--> Cross_Vertex form a cycle and we know that in tree , there are no cycles. ]

If anc2 is not the ancestor of A and anc2 , then there is no intersection. Reason : Follows from above. Let x be the ancestor of A and C. Then the problem reduces to finding intersection in 1D , given two segments [ A anc1 ] and [ x anc2 ].

Can you solve this ?
max(A,C) is lca(A,x) , min(B,D) is other vertex which is not lca(x,B).
Now you can see intersection is only possible if lca( max(A,C) , lca(A,x) ) is min(B,D)

Extra Input at the end

We missed to check in our test data about the extra input than required. Thanks to lyrically for pointing this out. We hope that such error will not happen in future. We are extremely sorry for this :( .

Time Complexity

O(log n) per update Query.
O(N) preprocessing.
O(log n) per Query [ Time required to find ancestor].

AUTHOR'S and TESTER'S SOLUTIONS:

Author's solution
Tester's solution

This question is marked "community wiki".

asked 22 Sep '14, 00:14

devuy11's gravatar image

4★devuy11 ♦♦
56273842
accept rate: 0%

edited 01 Oct '14, 21:23

So, let's get to bugfixes.

  • "Contest" link is wrong

  • Author's and tester's solution give Access Denied

(22 Sep '14, 00:18) xellos07★

upd: now the tester's solution is fixed, the other bugs are still there

(22 Sep '14, 03:20) xellos07★

upd2: now just the contest link is wrong.

(24 Sep '14, 10:50) xellos07★

now all links are fine :)

(24 Sep '14, 13:08) dpraveen ♦♦4★

Devendra Agarwal writes wonderful editorials. Especially for (medium-hard and hard) TREE related problems. I have also enjoyed reading his editorials at hackerrank. Great Work ! :-)

link

answered 23 Sep '14, 02:19

rsaha77's gravatar image

4★rsaha77
9663815
accept rate: 17%

edited 23 Sep '14, 02:23

"anc2 must lie in the path from A to anc1" shouldn't this be "anc2 must lie in the path from A to ROOT"? @admin Please clarify.

link

answered 23 Sep '14, 00:45

flaminrage's gravatar image

4★flaminrage
2442312
accept rate: 0%

1

No , it should be anc1 only because if anc1 is in between anc1 and Root then there is no common intersection as ancestor of anc1 and A is anc2 [ which implies that there is no common node in between anc1 and A]

(24 Sep '14, 13:15) devuy11 ♦♦4★
toggle preview
Preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported
  • mathemetical formulas in Latex between $ symbol

Question tags:

×15,482
×2,086
×1,236
×693
×242
×119

question asked: 22 Sep '14, 00:14

question was seen: 5,948 times

last updated: 01 Oct '14, 21:23