Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.76 KB | None | 0 0
  1. #pragma GCC optimize ("O3")
  2. #include <cstdio>
  3. #include <bits/stdc++.h>
  4.  
  5. #define scanf(args...) scanf(args) ? : 0
  6.  
  7. typedef std::pair<int, int> DistNode;
  8.  
  9. struct Node {
  10. constexpr static const DistNode NO_DIST_NODE = std::make_pair(-1, 0);
  11. static const int NO_NODE = -2;
  12. static const int LOG2_MAXN = 20;
  13. int left;
  14. int right;
  15. int height;
  16. int up[LOG2_MAXN];
  17. DistNode leftDist;
  18. DistNode rightDist;
  19. DistNode upDist;
  20. DistNode maxDist;
  21.  
  22. Node() {
  23. left = right = NO_NODE;
  24. leftDist = rightDist = upDist = maxDist = NO_DIST_NODE;
  25. std::fill(up, up + LOG2_MAXN, NO_NODE);
  26. }
  27.  
  28. };
  29.  
  30. class Tree {
  31. private:
  32. int n;
  33. std::vector <Node> nodes;
  34.  
  35. int findRoot() {
  36. auto rootIt = std::find_if(nodes.begin(), nodes.end(), [](const Node &node) {
  37. return node.up[0] == Node::NO_NODE;
  38. });
  39. assert(rootIt != nodes.end());
  40. return static_cast<int>(rootIt - nodes.begin());
  41. }
  42.  
  43. void setHeight(int v, int h) {
  44. if (v < 0) {
  45. return;
  46. }
  47. nodes[v].height = h;
  48. if (nodes[v].left != Node::NO_NODE) {
  49. setHeight(nodes[v].left, h + 1);
  50. }
  51. if (nodes[v].right != Node::NO_NODE) {
  52. setHeight(nodes[v].right, h + 1);
  53. }
  54. }
  55.  
  56. void setUp(int v, int index) {
  57. if (v < 0) {
  58. return;
  59. }
  60. if (nodes[v].up[index - 1] != Node::NO_NODE) {
  61. nodes[v].up[index] = nodes[nodes[v].up[index - 1]].up[index - 1];
  62. }
  63. if (nodes[v].left != Node::NO_NODE) {
  64. setUp(nodes[v].left, index);
  65. }
  66. if (nodes[v].right != Node::NO_NODE) {
  67. setUp(nodes[v].right, index);
  68. }
  69. }
  70.  
  71. void setLeftRightDistNodes(int v) {
  72. if (v < 0) {
  73. return;
  74. }
  75. int leftSon = nodes[v].left;
  76. if (leftSon != Node::NO_NODE) {
  77. setLeftRightDistNodes(leftSon);
  78. nodes[v].leftDist = nodes[leftSon].maxDist;
  79. nodes[v].leftDist.first++;
  80. }
  81. else {
  82. nodes[v].leftDist = {0, v};
  83. }
  84. int rightSon = nodes[v].right;
  85. if (rightSon != Node::NO_NODE) {
  86. setLeftRightDistNodes(rightSon);
  87. nodes[v].rightDist = nodes[rightSon].maxDist;
  88. nodes[v].rightDist.first++;
  89. }
  90. else {
  91. nodes[v].rightDist = {0, v};
  92. }
  93. nodes[v].maxDist = std::max(nodes[v].leftDist, nodes[v].rightDist);
  94. /*printf("Setting left/rightDistNodes for %d\n", v + 1);
  95. printf("Left: %d (dist = %d) Right: %d (dist = %d) Max: %d (dist = %d)\n",
  96. nodes[v].leftDist.second, nodes[v].leftDist.first,
  97. nodes[v].rightDist.second, nodes[v].rightDist.first,
  98. nodes[v].maxDist.second, nodes[v].maxDist.first);*/
  99. }
  100.  
  101. void setUpDistNodes(int v) {
  102. if (v < 0) {
  103. return;
  104. }
  105. int parent = nodes[v].up[0];
  106. if (parent != Node::NO_NODE) {
  107. nodes[v].upDist = nodes[parent].upDist;
  108. nodes[v].upDist.first++;
  109. if (nodes[parent].left == v) {
  110. DistNode upRightPath = nodes[parent].rightDist;
  111. upRightPath.first++;
  112. nodes[v].upDist = std::max(nodes[v].upDist, upRightPath);
  113. }
  114. else {
  115. DistNode upLeftPath = nodes[parent].leftDist;
  116. upLeftPath.first++;
  117. nodes[v].upDist = std::max(nodes[v].upDist, upLeftPath);
  118. }
  119. }
  120. else {
  121. nodes[v].upDist = {0, v};
  122. }
  123. nodes[v].maxDist = std::max(nodes[v].maxDist, nodes[v].upDist);
  124. if (nodes[v].left != Node::NO_NODE) {
  125. setUpDistNodes(nodes[v].left);
  126. }
  127. if (nodes[v].right != Node::NO_NODE) {
  128. setUpDistNodes(nodes[v].right);
  129. }
  130. }
  131.  
  132. void setDistNodes(int v) {
  133. if (v < 0) {
  134. return;
  135. }
  136. setLeftRightDistNodes(v);
  137. setUpDistNodes(v);
  138. }
  139.  
  140. int goUp(int x, int dist) {
  141. if (dist == 0) {
  142. return x;
  143. }
  144. int magic = dist & (-dist);
  145. dist -= magic;
  146. magic--;
  147. return goUp(nodes[x].up[__builtin_popcount(magic)], dist);
  148. }
  149.  
  150. int query(int x, int dist) {
  151. //printf("Max from %d is %d (dst = %d)\n", x, nodes[x].maxDist.second, nodes[x].maxDist.first);
  152. if (dist > nodes[x].maxDist.first) {
  153. return Node::NO_NODE;
  154. }
  155. //printf("Height %d is %d\n", x, nodes[x].height);
  156. if (nodes[x].height >= dist) {
  157. return goUp(x, dist);
  158. }
  159. //printf("QUERY: %d %d\n", dist, nodes[x].maxDist.first);
  160. return goUp(nodes[x].maxDist.second, nodes[x].maxDist.first - dist);
  161. }
  162.  
  163. public:
  164. Tree() = default;
  165.  
  166. void input() {
  167. scanf("%d", &n);
  168. nodes.resize(n);
  169. int a, b;
  170. for (int i = 0; i < n; i++) {
  171. scanf("%d%d", &a, &b);
  172. a--;
  173. b--;
  174. nodes[i].left = a;
  175. nodes[i].right = b;
  176. if (a != Node::NO_NODE) {
  177. nodes[a].up[0] = i;
  178. }
  179. if (b != Node::NO_NODE) {
  180. nodes[b].up[0] = i;
  181. }
  182. }
  183. }
  184.  
  185. void preprocess() {
  186. int root = findRoot();
  187. setHeight(root, 0);
  188. for (int i = 1; i < Node::LOG2_MAXN; i++) {
  189. setUp(root, i);
  190. }
  191. setDistNodes(root);
  192. }
  193.  
  194. void queries() {
  195. int m, x, dist;
  196. scanf("%d", &m);
  197. while (m--) {
  198. scanf("%d%d", &x, &dist);
  199. x--;
  200. printf("%d\n", query(x, dist) + 1);
  201. }
  202. }
  203. };
  204.  
  205.  
  206. int main() {
  207. Tree tree;
  208. tree.input();
  209. tree.preprocess();
  210. tree.queries();
  211. return 0;
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement