- import java.util.*; 
- import java.lang.*; 
- import java.io.*; 
-   
- class AreaCalculator 
- { 
- 	public static void-  main  (String[]-  args )	{
 
- 		//  _ 
-         // | |_ 
-         // |_ _ | 
- 		Direction[] input = { Direction.Up, Direction.Up,  
- 							  Direction.Right, Direction.Down, 
- 							  Direction.Right, Direction.Down, 
- 							  Direction.Left, Direction.Left }; 
-   
- 		System- . out- . println(- computeArea (- input ));
 
-   
- 		//  _ 
-         // |_|_ 
-         //   |_| 
- 		Direction[] input2 = { Direction.Up, Direction.Right,  
- 						  	   Direction.Down, Direction.Down, 
- 							   Direction.Right, Direction.Up, 
- 							   Direction.Left, Direction.Left }; 
-   
- 		System- . out- . println(- computeArea (- input2 ));
 
- 	} 
-   
- 	private static int computeArea(Direction[] directions) { 
- 		int leftmostIndex = 0; 
- 		for (int i = 0; i < directions.length; i++) { 
- 			Direction direction = directions[i]; 
- 			x = x + (direction == Direction.Left ? -1 : direction == Direction.Right ? 1 : 0); 
- 			xMax = x > xMax ? x : xMax; 
- 			if (x < xMin) { 
- 				xMin = x; 
- 				leftmostIndex = (i + 1) % directions.length; 
- 			} 
- 		} 
-   
- 		MaxHeap[] heaps = new MaxHeap[xMax - xMin]; 
- 		for (int i = 0; i < heaps.length; i++) heaps[i] = new MaxHeap(4); 
-   
- 		x = 0; 
- 		int y = 0; 
- 		int index = leftmostIndex; 
-   
- 		do { 
- 			Direction direction = directions[index]; 
- 			switch (direction) { 
- 				case Left: heaps[--x].add(y); break; 
- 				case Right: heaps[x++].add(y); break; 
- 				case Up: y++; break; 
- 				case Down: y--; break; 
- 			} 
- 			index = (index + 1) % directions.length; 
- 		} while (index != leftmostIndex); 
-   
- 		int area = 0; 
- 		for (MaxHeap heap : heaps) { 
- 			while (!heap.isEmpty()) { 
- 				area += heap.popMax() - heap.popMax(); 
- 			} 
- 		} 
-   
- 		return area; 
- 	} 
-   
- 	enum Direction { 
- 		Left, 
- 		Right, 
- 		Up, 
- 		Down 
- 	} 
-   
- 	private static class MaxHeap { 
- 		private int[] data; 
- 		private int size; 
- 		private int maxSize; 
-   
- 		public MaxHeap(int maxSize) { 
- 			this.maxSize = maxSize; 
- 			this.data = new int[maxSize]; 
- 			this.size = 0; 
- 		} 
-   
- 		public void add(int value) { 
- 			if (size == maxSize) { 
- 				int[] oldData = data; 
- 				maxSize *= 2; 
- 				data = new int[maxSize]; 
- 				System- . arraycopy(- oldData,  0- , data,  0- , size );
 
- 			} 
-   
- 			// bubble up 
- 			int index = size; 
- 			while (index > 0  && data[parent(index)] < value) { 
- 				data[index] = data[parent(index)]; 
- 				index = parent(index); 
- 			} 
- 			data[index] = value; 
-   
- 			size++; 
- 		} 
-   
- 		public int popMax() { 
- 			assert(size > 0); 
-   
- 			int max = data[0]; 
-   
- 			size--; 
- 			int value = data[size]; 
-   
- 			// bubble down 
- 			int index = 0; 
- 			int largerChild; 
- 			while (left(index) < size) { 
- 				if (right(index) < size) { 
- 					largerChild = data[left(index)] > data[right(index)] 
- 									? left(index) 
- 									: right(index); 
- 				} else { 
- 					largerChild = left(index); 
- 				} 
-   
- 				if (value > data[largerChild]) break; 
-   
- 				data[index] = data[largerChild]; 
- 				index = largerChild; 
- 			} 
- 			data[index] = value; 
-   
- 			return max; 
- 		} 
-   
- 		public boolean isEmpty() { 
- 			return size == 0; 
- 		} 
-   
- 		private static int parent(int i) { 
- 			return (i - 1) / 2; 
- 		} 
-   
- 		private static int left(int i) { 
- 			return 2 * i + 1; 
- 		} 
-   
- 		private static int right(int i) { 
- 			return 2 * i + 2; 
- 		} 
- 	} 
- }