Balkan OI 2017 - City Attractions
Author: Andi Qu
Introduction
Let the node that Gigel goes to from node be . Since the graph made from the directed edges is a functional graph, we can use binary jumping or any other efficient method to find the final node.
Now we only need to find all and we are done! However, this isn't as straightforward as it sounds...
A simpler problem
Let's consider a simpler problem: suppose we root the tree at node and Gigel can only move down the tree (don't worry about the leaves). In this problem, we can find all (and ) using a simple tree DP:
Let be the node in the subtree of (excluding itself) such that is maximized. Additionally, we store this value in the DP array. We can find by taking the best of and over all children of .
This algorithm runs in time.
Finding all
Obviously, the solution to the simpler problem doesn't solve the general problem: we might need to move up into a node's parent!
To address this issue, we can first do a DFS to find as defined above, and then do a second DFS to allow moving outside our subtree. See the solving for all roots module if you're unfamiliar with this technique. Essentially, we find the best destination from if we move up into 's parent and then compare that with .
After doing this, is simply as desired.
Finding the final destination
There are two ways we can go about finding Gigel's final location.
- We can implement binary jumping on our array containing the next location
- We try to reach a cycle, and then take our remaining jumps modulo the cycle size
The first method is a tad easier to implement, but introduces a log factor.
Implementation 1
Time Complexity:
#include <bits/stdc++.h>using namespace std;using ll = long long;int main() {int n;ll k;cin >> n >> k;
Implementation 2
Time Complexity:
#include <bits/stdc++.h>using namespace std;using ll = long long;int main() {int n;ll k;cin >> n >> k;
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!