Please, try EDU on Codeforces! New educational section with videos, subtitles, texts, and problems. ×

### Gagandeep98's blog

By Gagandeep98, history, 4 weeks ago, ,

I am stuck on Counting Path 1136 problem, and unable to think how to write an approach optimal to given constraints. Any hint or help is highly appreciated.

I cannot find any place where there is any hint for CSES problems(Except DP and Range Queries), hence thought this as the only possible option.

• 0

 » 4 weeks ago, # | ← Rev. 4 →   +13 Seems like a classic LCA + Segment tree problem.Flatten the tree using dfs and update on the range by 1 from index of a to index of b for every path. (Update the subtree of LCA(a,b) by 1 and the subtrees of node a and node b by -1 (dont forget to update extra 1 for node a and node b specifically)).There are edge cases, make sure you handle them.Print all the segment tree values for all nodes in the end.
•  » » 4 weeks ago, # ^ |   +8 Thank you! But why is segment tree needed? I think LCA + array for range is sufficient.
•  » » » 4 weeks ago, # ^ |   +5 Whatever you are comfortable with for range updates, works. I am much more comfortable with ST, hence mentioned that.
•  » » » » 4 weeks ago, # ^ |   +3 Right, thanks :)
•  » » » » » 4 weeks ago, # ^ |   0 No problem :)
•  » » 4 weeks ago, # ^ | ← Rev. 2 →   0 Can you please clarify one thing? Suppose I had a tree as shown below : EXAMPLE TREE Now let us assume that for the current path a=7 and b =5. So according to your algorithm, we will first find the of lca of a and b so here lca(a,b)=1 and then we'll add 1 to the subtree of node 1 and then add -1 to subtree of node 5 and node 7 (in this way we took care of nodes 10,11,12 and 9 that no update is made on them) but what about nodes 4,8 and 6 shouldn't we subtract 1 from them too? Sorry if I asked something very obvious or interpreted your algorithm incorrectly. EDIT: Got an AC by using (kind of)prefix sum approach using lca on the tree CODE FOR REFERENCE #include using namespace std; const int mxN =2e5+2 ; typedef vector vi; #define pb push_back #define For(i,n) for(int i=0;i=d[v]) u=anc[u][i] ; if(u==v) return u ; for(int i =17;~i;--i){ if(anc[u][i]^anc[v][i]){ u=anc[u][i],v=anc[v][i] ; } } return anc[u][0] ; } int dfs3(int v,int p){ c[v]=a[v] ; for(int x:adj[v]) if(x^p) c[v]+=dfs3(x,v); return c[v] ; } signed main() { memset(a,0,sizeof(a)) ; cin >> n >> m ; For(i,n-1){ int u,v ; cin >> u >> v ; adj[v].pb(u) ;adj[u].pb(v) ; } dfs2(1,0) ; vectork(n+1); For(i,m){ int u,v,l;cin >> u >> v ; l = lca(u,v) ; k[l]++ ; ++a[u];++a[v];a[l]-=2 ; } dfs3(1,0) ; for(int i=1;i<=n;i++) cout << c[i]+k[i] << " " ; } 
 » 4 weeks ago, # | ← Rev. 2 →   +2 There are complicated data structure solutions to this problem. But this one can actually be solved by doing prefix sums on difference array on tree.Break down each path into two vertical paths. Now, for each vertical path, in some vertex indexed array, do +1 for deeper point of vertical path and -1 for higher point. After this, just do subteee sum of values in the vertex indexed array. It will represent paths going out of a vertex, which is what you wanted.78837236 Accepted solution for an almost same problem on Codeforces
•  » » 4 weeks ago, # ^ |   0 Thanks a ton, it really helped a lot !!
•  » » 4 weeks ago, # ^ |   0 Yes, I also did in a similar way :)