Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <cstring>
- using namespace std;
- const int MAX_SIZE = 500002;
- int treeSize;
- // input rework stuff
- int nextVert[MAX_SIZE][3];
- int edgeCount[MAX_SIZE];
- // LA stuff goes here
- int p[MAX_SIZE];
- int depth[MAX_SIZE];
- vector<int> leavesOfDepth[MAX_SIZE];
- int whichPath[MAX_SIZE];
- vector<int> paths[MAX_SIZE];
- int pathIdx = 0;
- vector<vector<int>> ladders;
- vector<int> nodeLadder[MAX_SIZE];
- void inputTree();
- void makeTree(); // make the parent function and calculate depths
- void findLeaves();
- void findPaths();
- void buildLadders();
- int levelAncestorNaive(int node, int level);
- int levelAncestorSqrt(int node, int level);
- int levelAncestorLog(int node, int level);
- int main()
- {
- ios_base::sync_with_stdio(false);
- inputTree();
- makeTree();
- findLeaves();
- findPaths();
- buildLadders();
- int q;
- cin >> q;
- int vert, k;
- while (q--)
- {
- cin >> vert >> k;
- cout << levelAncestorLog(vert, k) << endl;
- }
- //system("pause");
- return 0;
- }
- int levelAncestorLog(int node, int level)
- {
- if (level == 0) return node;
- if (level > depth[node]) return -1;
- while (level)
- {
- int pathIdx = whichPath[node];
- vector<int> &path = paths[pathIdx];
- int tail = path.back();
- int idx = depth[node] - level - depth[tail];
- if (idx >= 0) // it's in the path
- {
- int resultIdx = path.size() - 1 - idx;
- int retVal = path[resultIdx];
- return retVal;
- }
- idx = -idx - 1;
- vector<int> &ladder = ladders[pathIdx];
- if (idx < ladder.size()) // it's in the ladder
- {
- return ladder[idx];
- }
- int next = p[ladder.back()];
- int diff = depth[next] - depth[node];
- level += diff;
- node = next;
- }
- return node;
- }
- int levelAncestorSqrt(int node, int level)
- {
- if (level == 0) return node;
- if (level > depth[node]) return -1;
- while (level)
- {
- int pathIdx = whichPath[node];
- vector<int> &path = paths[pathIdx];
- int tail = path.back();
- if (depth[node] - depth[tail] < level) // path is not enough (node == tail is also possible)
- {
- level -= depth[node] - depth[tail];
- node = p[tail];
- level--;
- }
- else
- {
- int offset = depth[node] - depth[tail] - level;
- node = path[path.size() - 1 - offset];
- break;
- }
- }
- return node;
- }
- int levelAncestorNaive(int node, int level)
- {
- if (level == 0) return node;
- if (level > depth[node]) return -1;
- while (level--) node = p[node];
- return node;
- }
- void buildLadders()
- {
- ladders.resize(pathIdx);
- for (int i = 0; i < pathIdx; i++)
- {
- vector<int> ¤t = ladders[i];
- int node = paths[i].back();
- int remaining = paths[i].size();
- while (remaining && node != 1)
- {
- node = p[node];
- current.push_back(node);
- remaining--;
- }
- }
- }
- void findPaths()
- {
- memset(whichPath, -1, MAX_SIZE * sizeof(int));
- int node;
- for (int i = treeSize - 1; i >= 0; i--) // start with the deepest leaves
- {
- vector<int> ¤t = leavesOfDepth[i];
- for (int j = 0; j < current.size(); j++)
- {
- node = current[j];
- paths[pathIdx].push_back(node);
- whichPath[node] = pathIdx;
- node = p[node];
- while (whichPath[node] == -1)
- {
- paths[pathIdx].push_back(node);
- whichPath[node] = pathIdx;
- node = p[node];
- }
- pathIdx++;
- }
- }
- }
- void findLeaves()
- {
- for (int i = 1; i <= treeSize; i++)
- {
- if (edgeCount[i] != 1) continue; // leaves have only one edge, the one connecting them to their parents
- int d = depth[i];
- leavesOfDepth[d].push_back(i);
- }
- }
- void makeTree()
- {
- p[1] = 1;
- depth[1] = 0;
- queue<int> q;
- q.push(1);
- while (!q.empty())
- {
- int current = q.front();
- q.pop();
- for (int i = 0; i < edgeCount[current]; i++)
- {
- int next = nextVert[current][i];
- if (p[next]) continue;
- p[next] = current;
- depth[next] = depth[current] + 1;
- q.push(next);
- }
- }
- }
- void inputTree()
- {
- cin >> treeSize;
- int src, dest;
- for (int i = 1; i < treeSize; i++)
- {
- cin >> src >> dest;
- nextVert[src][edgeCount[src]++] = dest;
- nextVert[dest][edgeCount[dest]++] = src;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement