Advertisement
Guest User

Untitled

a guest
Nov 20th, 2018
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.09 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <cstring>
  5.  
  6. using namespace std;
  7.  
  8. const int MAX_SIZE = 500002;
  9.  
  10. int treeSize;
  11.  
  12. // input rework stuff
  13. int nextVert[MAX_SIZE][3];
  14. int edgeCount[MAX_SIZE];
  15.  
  16. // LA stuff goes here
  17. int p[MAX_SIZE];
  18.  
  19. int depth[MAX_SIZE];
  20. vector<int> leavesOfDepth[MAX_SIZE];
  21.  
  22. int whichPath[MAX_SIZE];
  23. vector<int> paths[MAX_SIZE];
  24. int pathIdx = 0;
  25.  
  26. vector<vector<int>> ladders;
  27. vector<int> nodeLadder[MAX_SIZE];
  28.  
  29. void inputTree();
  30. void makeTree(); // make the parent function and calculate depths
  31. void findLeaves();
  32. void findPaths();
  33. void buildLadders();
  34.  
  35. int levelAncestorNaive(int node, int level);
  36. int levelAncestorSqrt(int node, int level);
  37. int levelAncestorLog(int node, int level);
  38.  
  39. int main()
  40. {
  41. ios_base::sync_with_stdio(false);
  42. inputTree();
  43. makeTree();
  44. findLeaves();
  45. findPaths();
  46. buildLadders();
  47.  
  48. int q;
  49. cin >> q;
  50. int vert, k;
  51.  
  52. while (q--)
  53. {
  54. cin >> vert >> k;
  55. cout << levelAncestorLog(vert, k) << endl;
  56. }
  57.  
  58. //system("pause");
  59. return 0;
  60. }
  61.  
  62. int levelAncestorLog(int node, int level)
  63. {
  64. if (level == 0) return node;
  65. if (level > depth[node]) return -1;
  66.  
  67. while (level)
  68. {
  69. int pathIdx = whichPath[node];
  70. vector<int> &path = paths[pathIdx];
  71.  
  72. int tail = path.back();
  73.  
  74. int idx = depth[node] - level - depth[tail];
  75. if (idx >= 0) // it's in the path
  76. {
  77. int resultIdx = path.size() - 1 - idx;
  78. int retVal = path[resultIdx];
  79. return retVal;
  80. }
  81.  
  82. idx = -idx - 1;
  83. vector<int> &ladder = ladders[pathIdx];
  84.  
  85. if (idx < ladder.size()) // it's in the ladder
  86. {
  87. return ladder[idx];
  88. }
  89.  
  90. int next = p[ladder.back()];
  91. int diff = depth[next] - depth[node];
  92. level += diff;
  93. node = next;
  94. }
  95.  
  96. return node;
  97. }
  98.  
  99. int levelAncestorSqrt(int node, int level)
  100. {
  101. if (level == 0) return node;
  102. if (level > depth[node]) return -1;
  103.  
  104. while (level)
  105. {
  106. int pathIdx = whichPath[node];
  107. vector<int> &path = paths[pathIdx];
  108.  
  109. int tail = path.back();
  110.  
  111. if (depth[node] - depth[tail] < level) // path is not enough (node == tail is also possible)
  112. {
  113. level -= depth[node] - depth[tail];
  114. node = p[tail];
  115. level--;
  116. }
  117. else
  118. {
  119. int offset = depth[node] - depth[tail] - level;
  120. node = path[path.size() - 1 - offset];
  121. break;
  122. }
  123. }
  124.  
  125. return node;
  126. }
  127.  
  128. int levelAncestorNaive(int node, int level)
  129. {
  130. if (level == 0) return node;
  131. if (level > depth[node]) return -1;
  132.  
  133. while (level--) node = p[node];
  134. return node;
  135. }
  136.  
  137. void buildLadders()
  138. {
  139. ladders.resize(pathIdx);
  140. for (int i = 0; i < pathIdx; i++)
  141. {
  142. vector<int> &current = ladders[i];
  143.  
  144. int node = paths[i].back();
  145. int remaining = paths[i].size();
  146.  
  147. while (remaining && node != 1)
  148. {
  149. node = p[node];
  150. current.push_back(node);
  151. remaining--;
  152. }
  153. }
  154. }
  155.  
  156. void findPaths()
  157. {
  158. memset(whichPath, -1, MAX_SIZE * sizeof(int));
  159.  
  160. int node;
  161. for (int i = treeSize - 1; i >= 0; i--) // start with the deepest leaves
  162. {
  163. vector<int> &current = leavesOfDepth[i];
  164. for (int j = 0; j < current.size(); j++)
  165. {
  166. node = current[j];
  167.  
  168. paths[pathIdx].push_back(node);
  169. whichPath[node] = pathIdx;
  170. node = p[node];
  171.  
  172. while (whichPath[node] == -1)
  173. {
  174. paths[pathIdx].push_back(node);
  175. whichPath[node] = pathIdx;
  176. node = p[node];
  177. }
  178.  
  179. pathIdx++;
  180. }
  181. }
  182. }
  183.  
  184. void findLeaves()
  185. {
  186. for (int i = 1; i <= treeSize; i++)
  187. {
  188. if (edgeCount[i] != 1) continue; // leaves have only one edge, the one connecting them to their parents
  189. int d = depth[i];
  190. leavesOfDepth[d].push_back(i);
  191. }
  192. }
  193.  
  194. void makeTree()
  195. {
  196. p[1] = 1;
  197. depth[1] = 0;
  198. queue<int> q;
  199.  
  200. q.push(1);
  201. while (!q.empty())
  202. {
  203. int current = q.front();
  204. q.pop();
  205.  
  206. for (int i = 0; i < edgeCount[current]; i++)
  207. {
  208. int next = nextVert[current][i];
  209. if (p[next]) continue;
  210.  
  211. p[next] = current;
  212. depth[next] = depth[current] + 1;
  213. q.push(next);
  214. }
  215. }
  216. }
  217.  
  218. void inputTree()
  219. {
  220. cin >> treeSize;
  221. int src, dest;
  222. for (int i = 1; i < treeSize; i++)
  223. {
  224. cin >> src >> dest;
  225. nextVert[src][edgeCount[src]++] = dest;
  226. nextVert[dest][edgeCount[dest]++] = src;
  227. }
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement