Advertisement
Guest User

Untitled

a guest
Mar 1st, 2015
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.39 KB | None | 0 0
  1. import java.io.File;
  2. import java.io.FileWriter;
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5. import java.util.Scanner;
  6.  
  7. /**
  8. * Created by lenovo on 2/17/2015.
  9. */
  10.  
  11. class Node{
  12. public long val;
  13. public int level;
  14. public int lengthTrace;
  15. public Node right;
  16. public Node left;
  17.  
  18. public boolean inTrace = false;
  19. public boolean moreThanOneVariant = true;
  20.  
  21. public Node endLeft;
  22. public Node endRight;
  23.  
  24. Node(int val) {
  25. this.val = val;
  26. this.level = 1;
  27. }
  28. }
  29.  
  30. public class Main {
  31.  
  32. private static Node root = new Node(Integer.MAX_VALUE);
  33. private static PrintWriter writer;
  34. private static Node theBestRoot;
  35.  
  36. private static int helpCount = 0;
  37. private static Node parentMedium;
  38. private static Node medium;
  39. private static Node afterMedium;
  40. private static Node parentAfterMedium;
  41.  
  42. public static Node add(Node cur, int value){
  43. if ( cur == null ){
  44. return new Node(value);
  45. }
  46. if (value < cur.val){
  47. cur.left = add(cur.left, value);
  48. } else {
  49. cur.right = add(cur.right, value);
  50. }
  51. return cur;
  52. }
  53.  
  54. public static void show(Node cur){
  55. if (cur == null) {
  56. return;
  57. }
  58. writer.println(cur.val /*+ " " + cur.level*/);
  59. show(cur.left);
  60. show(cur.right);
  61. }
  62.  
  63. public static int getLevel(Node node){
  64. if (node == null) return 0;
  65. return node.level;
  66. }
  67.  
  68. public static boolean firstBetter(Node first, Node second){
  69. if (second == null) return true;
  70. if (second.lengthTrace < first.lengthTrace) return true;
  71. if (second.lengthTrace > first.lengthTrace) return false;
  72. if (second.endLeft.val + second.endRight.val
  73. > first.endLeft.val + first.endRight.val) return true;
  74. if (second.endLeft.val + second.endRight.val
  75. < first.endLeft.val + first.endRight.val) return false;
  76. return (first.val < second.val); // ? maybe will be upgrade
  77. }
  78.  
  79. public static Node getList(Node node){
  80. if (node.left != null) return node.left;
  81. return node.right;
  82. }
  83.  
  84. public static Node getRightList(Node root, Node from){
  85. if ( root == from ) return root.right;
  86. return getList(from);
  87. }
  88.  
  89. public static Node getLeftList(Node root, Node from){
  90. if (root == from) return root.left;
  91. return getList(from);
  92. }
  93.  
  94. public static void init(Node node, Node endLeft, Node endRight){
  95. node.endLeft = endLeft;
  96. node.endRight = endRight;
  97. }
  98.  
  99. public static void findTraceWithRoot(Node node, Node leftNode, Node rightNode){
  100. boolean moreThanOneVariant = false; // !!! warning !!!
  101.  
  102. Node endNotRoot;
  103. if ( getLevel(node.left) >= getLevel(node.right) ){
  104. endNotRoot = getLeftList(node, leftNode);
  105. } else {
  106. endNotRoot = getRightList(node, rightNode);
  107. }
  108.  
  109. if (leftNode == null || rightNode == null){
  110. init(node, node, endNotRoot);
  111. node.lengthTrace = node.level;
  112. node.moreThanOneVariant = false;
  113. return;
  114. }
  115.  
  116. Node leftEnd = leftNode;
  117. Node rightEnd = rightNode;
  118. if (leftNode.val - getLeftList(node, leftNode).val >
  119. rightNode.val - getRightList(node, rightNode).val){
  120. leftEnd = getLeftList(node, leftNode);
  121. }
  122. if (leftNode.val - getLeftList(node, leftNode).val <= //attention
  123. rightNode.val - getRightList(node, rightNode).val){
  124. rightEnd = getRightList(node, rightNode);
  125. }
  126. if (leftNode.val - getLeftList(node, leftNode).val ==
  127. rightNode.val - getRightList(node, rightNode).val){
  128. moreThanOneVariant = true;
  129. }
  130.  
  131. if (leftEnd == node || rightEnd == node){
  132. init(node, node, endNotRoot);
  133. node.lengthTrace = node.level;
  134. node.moreThanOneVariant = false;
  135. return;
  136. }
  137.  
  138. int length = getLevel(node.left) + getLevel(node.right);
  139. if (node.level > length){
  140. init(node, node, endNotRoot);
  141. node.lengthTrace = node.level;
  142. node.moreThanOneVariant = false;
  143. return;
  144. }
  145. if (node.level < length){
  146. init(node, leftEnd, rightEnd);
  147. node.lengthTrace = length;
  148. node.moreThanOneVariant = moreThanOneVariant;
  149. return;
  150. }
  151.  
  152. if(node.val + endNotRoot.val < leftEnd.val + rightNode.val ){
  153. init(node, node, endNotRoot);
  154. node.lengthTrace = length;
  155. node.moreThanOneVariant = false;
  156. return;
  157. }
  158. if (node.val + endNotRoot.val == leftEnd.val + rightNode.val){
  159. moreThanOneVariant = true;
  160. }
  161. if (node.val + endNotRoot.val >= leftEnd.val + rightNode.val){ // attention
  162. init(node, leftEnd, rightNode);
  163. node.lengthTrace = length;
  164. node.moreThanOneVariant = moreThanOneVariant;
  165. }
  166. }
  167.  
  168.  
  169.  
  170. public static Node preCalc(Node cur, Node parent){
  171. if (cur == null) return null;
  172.  
  173. if ( cur.left == null && cur.right == null ){
  174. cur.level = 1;
  175. return parent;
  176. }
  177.  
  178. Node leftNode = preCalc(cur.left, cur);
  179. Node rightNode = preCalc(cur.right, cur);
  180.  
  181. cur.level = Math.max(getLevel(cur.left), getLevel(cur.right)) + 1;
  182.  
  183. findTraceWithRoot(cur, leftNode, rightNode);
  184. if ( firstBetter(cur, theBestRoot) ){
  185. theBestRoot = cur;
  186. }
  187.  
  188. if ( getLevel(cur.left) >= getLevel(cur.right)){
  189. return leftNode;
  190. } else {
  191. return rightNode;
  192. }
  193. }
  194.  
  195. public static boolean markTrace(Node cur){
  196. if ( cur == null ) return false;
  197. cur.inTrace |= markTrace(cur.left);
  198. cur.inTrace |= markTrace(cur.right);
  199.  
  200. if (cur == theBestRoot.endLeft || cur == theBestRoot.endRight){
  201. cur.inTrace = true;
  202. }
  203. return cur.inTrace;
  204. }
  205.  
  206. public static void prepareToDelete(Node cur, Node parent){
  207. if (cur == null) return;
  208.  
  209. prepareToDelete(cur.left, cur);
  210.  
  211. if (cur.inTrace) {
  212. ++helpCount;
  213. }
  214. if (medium != null && afterMedium == null){
  215. afterMedium = cur;
  216. parentAfterMedium = parent;
  217. }
  218. if ( medium == null && helpCount > theBestRoot.lengthTrace / 2){
  219. medium = cur;
  220. parentMedium = parent;
  221. }
  222.  
  223. prepareToDelete(cur.right, cur);
  224. }
  225.  
  226. public static void changeLinkParent(Node parent, Node child, Node newChild){
  227. if (parent.left == child){
  228. parent.left = newChild;
  229. } else {
  230. parent.right = newChild;
  231. }
  232. }
  233.  
  234. public static void deleteMedium(){
  235.  
  236. if ( medium.left == null && medium.right == null){
  237. changeLinkParent(parentMedium, medium, null);
  238. return;
  239. }
  240. if ( medium.left == null ){
  241. changeLinkParent(parentMedium, medium, medium.right);
  242. return;
  243. }
  244. if ( medium.right == null ){
  245. changeLinkParent(parentMedium, medium, medium.left);
  246. return;
  247. }
  248.  
  249. changeLinkParent(parentMedium, medium, afterMedium);
  250. afterMedium.left = medium.left;
  251. if (medium.right != afterMedium) {
  252. afterMedium.right = medium.right;
  253. }
  254. changeLinkParent(parentAfterMedium, afterMedium, null);
  255.  
  256. }
  257.  
  258. public static void main(String[] args) throws IOException{
  259. Scanner scanner = new Scanner( new File("tst.in"));
  260. FileWriter fw = new FileWriter("tst.out");
  261. writer = new PrintWriter(fw);
  262.  
  263. while (scanner.hasNext()){
  264. int temp = scanner.nextInt();
  265. add(root, temp);
  266. }
  267.  
  268. preCalc(root.left, root);
  269.  
  270. if ( ( root.left.level != 1 ) && ( theBestRoot.lengthTrace % 2 == 1 )
  271. && (!theBestRoot.moreThanOneVariant) ){
  272. markTrace(theBestRoot);
  273. prepareToDelete(root.left, root);
  274. deleteMedium();
  275. }
  276.  
  277. show(root.left); // case with one !!!!
  278.  
  279. writer.flush();
  280. writer.close();
  281. }
  282. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement