Explanation
First, instead of trying to tackle the problem for arbitrary values of , let's try calculating the number of steps it takes for each node to reach node .
When at a fountain, we will only ever take the two most beautiful outgoing trails. Let's consider a graph, where we draw edges between states. Each state is represented as a pair , where:
- is our current node
- represents whether we are taking the most beautiful trail
- means we can take the most beautiful trail
- means we can only take the second most beautiful trail
Now, we want to find the distance from every other state to . Finding the distances to can be handled in a similar fashion.
We can use our graph traversal method of choice to traverse from out to all of our other states. To handle this, we construct a reversed graph, and traverse out from to other states. After calculating the distances, we know that the distance from any node to our state is the distance from to . We handle similarly.
Alright, so now we know how to calculate the distance from every node to . How do we handle large values of ?
Consider the fact that each state will directly map to another state, forming a successor graph. Thus, if we arrive at or at any point, one of the following must happen:
- We arrive at , and end up in a cycle where is not present
- We arrive at , and cycle back to
- We arrive at , encounter , and loop back to
Say our state falls under the second scenario, where it ends up in a cycle of length . Then, for a node to be able to reach after trails, the following must be true for some non-negative integer :
Scenarios 1 and 3 can be handled in a similar fashion. For scenario 3, we have to store the time that we visit the state in our cycle.
With this, we can solve each query in by checking each node and seeing if it ends up at , using the three cases outlined above.
Implementation
Time Complexity:
C++
#include "garden.h"#include "gardenlib.h"#include <bits/stdc++.h>using ll = long long;constexpr int INF = 1e9;void count_routes(int n, int m, int p, int r[][2], int q, int g[]) {std::vector<std::vector<std::array<int, 2>>> adj(n);
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!