CSES - Fixed-Length Paths II

Authors: Andi Qu, Benjamin Qi

Time Complexity: O(Nlog2N)\mathcal O(N \log^2 N).

This solution is a simple extension of CSES Fixed-Length Paths I's solution.

Since we want to count the number of paths of length between aa and bb instead of a fixed length kk, a node with depth dd in uu's ii-th child's subtree will contribute x=adbdcnti1[x]\sum_{x = a - d}^{b - d}\texttt{cnt}_{i - 1}[x] paths instead of cnti1[kd]\texttt{cnt}_{i - 1}[k - d] paths to the answer.

This is a range sum, so we can use any range-sum data-structure (e.g. a BIT) to query and update cnt\texttt{cnt} efficiently. This adds an additional logN\log N factor to the complexity.

C++

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int n, a, b;
vector<int> graph[200001];
int subtree[200001];
ll ans = 0, bit[200001];
int mx_depth;

Bonus Solution

It's also possible to solve this problem in linear time!

We use the same idea as the above solution but with prefix sums instead of a BIT and with small-to-large merging in a single DFS instead of centroid decomposition. This is because we can merge two prefix sum arrays AA and BB in O(min(A,B))\mathcal O(\min(|A|, |B|)) time.

If we let did_i denote the maximum depth in node ii's subtree, then the resulting time complexity is

O(i=1N(dimaxci’s children(dc))).\mathcal O\left(\sum_{i = 1}^N\left(d_i - \max_{c \in i \text{'s children}}(d_c)\right)\right).

Since di=maxci’s children(dc)+1d_i = \max_{c \in i \text{'s children}}(d_c) + 1, the above expression simplifies to O(N)\mathcal O(N) - a significant improvement from our first solution!

Below is Ben's code implementing this idea:

C++

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using db = long double; // or double, if TL is tight
using str = string; // yay python!
using pi = pair<int,int>;
using pl = pair<ll,ll>;
using pd = pair<db,db>;

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!