Advertisement
Guest User

Untitled

a guest
Oct 26th, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.66 KB | None | 0 0
  1. import java.io.BufferedReader;
  2. import java.io.FileReader;
  3. import java.io.PrintWriter;
  4. import java.util.ArrayList;
  5.  
  6. /**
  7. * Created by aleksandr on 25.10.16.
  8. */
  9. class SegmentTree {
  10.  
  11. class SegmentPair {
  12. int value;
  13. int index;
  14.  
  15. SegmentPair(int val, int ind) {
  16. value = val;
  17. index = ind;
  18. }
  19. }
  20.  
  21. SegmentPair min(SegmentPair a, SegmentPair b) {
  22. if (a.value < b.value) {
  23. return a;
  24. } else return b;
  25. }
  26.  
  27. ArrayList<SegmentPair> segmTree;
  28.  
  29. private int closestTwoPow(int n) {
  30. for (int i = 0; ; i++) {
  31. if (Math.pow(2, i) >= n)
  32. return (int) Math.pow(2, i);
  33. }
  34. }
  35.  
  36. SegmentTree(ArrayList<Integer> basicArray) {
  37. //building segment tree for range minimum query
  38. int newSize = closestTwoPow(basicArray.size());
  39. segmTree = new ArrayList<SegmentPair>(newSize * 2 - 1);
  40.  
  41. //tmp wtf
  42. for (int i = 0; i < newSize * 2 - 1; i++)
  43. segmTree.add(new SegmentPair(0, 0));
  44.  
  45. for (int i = segmTree.size() - newSize; i < segmTree.size() - newSize + basicArray.size(); i++) {
  46. segmTree.set(i, new SegmentPair(basicArray.get(i - newSize + 1), i - newSize + 1));
  47. }
  48. for (int i = segmTree.size() - newSize + basicArray.size(); i < segmTree.size(); i++) {
  49. segmTree.set(i, new SegmentPair(Integer.MAX_VALUE, 0));
  50. }
  51. for (int i = segmTree.size() - 1 - newSize; i >= 0; i--) {
  52. segmTree.set(i, min(segmTree.get(2 * i + 1), segmTree.get(2 * i + 2)));
  53. }
  54.  
  55. //segment tree for given array built successfully
  56. }
  57.  
  58. //pre:
  59. // indices are accepted in base array, not in segmTree array
  60. //post:
  61. // returns index of minimal element in range
  62. public int rangeMinQuery(int l, int r) {
  63. //we have to find minimum on the range from l to r indices in array
  64. l += segmTree.size() / 2;
  65. r += segmTree.size() / 2;
  66. SegmentPair ans = new SegmentPair(Integer.MAX_VALUE, 0);
  67.  
  68. while (true) {
  69.  
  70. //if l is right child
  71. if (l / 2 - 1 == (l - 1) / 2) {
  72. ans = min(ans, segmTree.get(l));
  73. l++;
  74. }
  75.  
  76. //if r is left child
  77. if (r / 2 - 1 != (r - 1) / 2) {
  78. ans = min(ans, segmTree.get(r));
  79. r--;
  80. }
  81.  
  82. if (r < l) break;
  83.  
  84. //going one level up:
  85. if (l / 2 - 1 != (l - 1) / 2) {
  86. l = l / 2;
  87. } else {
  88. l = l / 2 - 1;
  89. }
  90.  
  91. if (r / 2 - 1 != (r - 1) / 2) {
  92. r = r / 2;
  93. } else {
  94. r = r / 2 - 1;
  95. }
  96. }
  97. return ans.index;
  98. }
  99. }
  100.  
  101. class Tree {
  102. class Node {
  103. int number;
  104. ArrayList<Node> children;
  105.  
  106. Node(int num) {
  107. number = num;
  108. children = new ArrayList<Node>();
  109. }
  110. }
  111.  
  112. Node root;
  113. ArrayList<Node> arrNodes;
  114.  
  115. ArrayList<Integer> numberNode;
  116. ArrayList<Integer> depthNode;
  117. ArrayList<Integer> indexesNode;
  118.  
  119. //reads input and builds a tree
  120. Tree(BufferedReader br) throws Exception {
  121. String str;
  122. int n = Integer.parseInt(br.readLine());
  123.  
  124. arrNodes = new ArrayList<Node>();
  125.  
  126. root = new Node(1);
  127. arrNodes.add(root);//adding root with no parent
  128.  
  129. for (int i = 2; i <= n; i++) {
  130. Node tmp = new Node(i);
  131. arrNodes.add(tmp);
  132. arrNodes.get(Integer.parseInt(br.readLine()) - 1).children.add(tmp);
  133. }
  134. //tree built from input
  135. }
  136.  
  137. void eulerTrip() {
  138. numberNode = new ArrayList<Integer>();
  139. depthNode = new ArrayList<Integer>();
  140. indexesNode = new ArrayList<Integer>();
  141.  
  142. for (int i = 0; i < arrNodes.size(); i++) // resize
  143. indexesNode.add(0);
  144.  
  145. recursiveTrip(this.root, 1);
  146. }
  147.  
  148. void recursiveTrip(Node nod, int currentDepth) {
  149. indexesNode.set(nod.number - 1, numberNode.size());
  150. for (int i = 0; i < nod.children.size(); i++) {
  151. numberNode.add(nod.number);
  152. depthNode.add(currentDepth);
  153. recursiveTrip(nod.children.get(i), currentDepth + 1);
  154. }
  155. numberNode.add(nod.number);
  156. depthNode.add(currentDepth);
  157. }
  158. }
  159.  
  160. public class LcaRmq {
  161.  
  162. public static void main(String[] args) throws Exception {
  163. final String input = "lca.in";
  164. final String output = "lca.out";
  165.  
  166. BufferedReader br = new BufferedReader(new FileReader(input));
  167.  
  168. Tree tr = new Tree(br);
  169. tr.eulerTrip();
  170.  
  171. int m = Integer.parseInt(br.readLine());
  172.  
  173. SegmentTree st = new SegmentTree(tr.depthNode);
  174.  
  175. PrintWriter writer = new PrintWriter(output);
  176.  
  177. for (int i = 0; i < m; i++) {
  178. String[] parts = br.readLine().split(" ");
  179. int firstNodeIndexInArrayOfDepths = tr.indexesNode.get(Integer.parseInt(parts[0]) - 1);
  180. int secondNodeIndexInArrayOfDepths = tr.indexesNode.get(Integer.parseInt(parts[1]) - 1);
  181. if(firstNodeIndexInArrayOfDepths > secondNodeIndexInArrayOfDepths)
  182. {
  183. //swap wtf
  184. int tmp = secondNodeIndexInArrayOfDepths;
  185. secondNodeIndexInArrayOfDepths = firstNodeIndexInArrayOfDepths;
  186. firstNodeIndexInArrayOfDepths = tmp;
  187. }
  188. writer.println(tr.numberNode.get(st.rangeMinQuery(firstNodeIndexInArrayOfDepths, secondNodeIndexInArrayOfDepths)));
  189. }
  190. writer.close();
  191. }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement