Advertisement
kartikkukreja

Median

Apr 12th, 2013
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 13.85 KB | None | 0 0
  1. import java.util.*;
  2.  
  3. public class Median {
  4.  
  5.     private class IndexMaxPQ<Key extends Comparable<Key>> implements Iterable<Integer> {
  6.         private int N;           // number of elements on PQ
  7.         private int[] pq;        // binary heap using 1-based indexing
  8.         private int[] qp;        // inverse of pq - qp[pq[i]] = pq[qp[i]] = i
  9.         private Key[] keys;      // keys[i] = priority of i
  10.  
  11.        /**
  12.          * Create an empty indexed priority queue with indices between 0 and NMAX-1.
  13.          * @throws java.lang.IllegalArgumentException if NMAX < 0
  14.          */
  15.         public IndexMaxPQ(int NMAX) {
  16.             keys = (Key[]) new Comparable[NMAX + 1];    // make this of length NMAX??
  17.             pq   = new int[NMAX + 1];
  18.             qp   = new int[NMAX + 1];                   // make this of length NMAX??
  19.             for (int i = 0; i <= NMAX; i++) qp[i] = -1;
  20.         }
  21.  
  22.        /**
  23.          * Is the priority queue empty?
  24.          */
  25.         public boolean isEmpty() { return N == 0; }
  26.  
  27.        /**
  28.          * Is i an index on the priority queue?
  29.          * @throws java.lang.IndexOutOfBoundsException unless (0 &le; i < NMAX)
  30.          */
  31.         public boolean contains(int i) {
  32.             return qp[i] != -1;
  33.         }
  34.  
  35.  
  36.        /**
  37.          * Return the number of keys on the priority queue.
  38.          */
  39.         public int size() {
  40.             return N;
  41.         }
  42.  
  43.        /**
  44.          * Associate key with index i.
  45.          * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
  46.          * @throws java.util.IllegalArgumentException if there already is an item associated with index i.
  47.          */
  48.         public void insert(int i, Key key) {
  49.             if (contains(i)) throw new IllegalArgumentException("index is already in the priority queue");
  50.             N++;
  51.             qp[i] = N;
  52.             pq[N] = i;
  53.             keys[i] = key;
  54.             swim(N);
  55.         }
  56.  
  57.        /**
  58.          * Return a minimal key.
  59.          * @throws java.util.NoSuchElementException if priority queue is empty.
  60.          */
  61.         public Key maxKey() {
  62.             if (N == 0) throw new NoSuchElementException("Priority queue underflow");
  63.             return keys[pq[1]];
  64.         }
  65.  
  66.        /**
  67.          * Delete a maximal key and return its associated index.
  68.          * @throws java.util.NoSuchElementException if priority queue is empty.
  69.          */
  70.         public int delMax() {
  71.             if (N == 0) throw new NoSuchElementException("Priority queue underflow");
  72.             int min = pq[1];        
  73.             exch(1, N--);
  74.             sink(1);
  75.             qp[min] = -1;            // delete
  76.             keys[pq[N+1]] = null;    // to help with garbage collection
  77.             pq[N+1] = -1;            // not needed
  78.             return min;
  79.         }
  80.  
  81.        /**
  82.          * Delete the key associated with index i.
  83.          * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
  84.          * @throws java.util.NoSuchElementException no key is associated with index i
  85.          */
  86.         public void delete(int i) {
  87.             if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
  88.             int index = qp[i];
  89.             exch(index, N--);
  90.             swim(index);
  91.             sink(index);
  92.             keys[i] = null;
  93.             qp[i] = -1;
  94.         }
  95.  
  96.  
  97.        /**************************************************************
  98.         * General helper functions
  99.         **************************************************************/
  100.         private boolean less(int i, int j) {
  101.             return keys[pq[i]].compareTo(keys[pq[j]]) < 0;
  102.         }
  103.  
  104.         private void exch(int i, int j) {
  105.             int swap = pq[i]; pq[i] = pq[j]; pq[j] = swap;
  106.             qp[pq[i]] = i; qp[pq[j]] = j;
  107.         }
  108.  
  109.  
  110.        /**************************************************************
  111.         * Heap helper functions
  112.         **************************************************************/
  113.         private void swim(int k)  {
  114.             while (k > 1 && less(k/2, k)) {
  115.                 exch(k, k/2);
  116.                 k = k/2;
  117.             }
  118.         }
  119.  
  120.         private void sink(int k) {
  121.             while (2*k <= N) {
  122.                 int j = 2*k;
  123.                 if (j < N && less(j, j+1)) j++;
  124.                 if (!less(k, j)) break;
  125.                 exch(k, j);
  126.                 k = j;
  127.             }
  128.         }
  129.  
  130.  
  131.        /***********************************************************************
  132.         * Iterators
  133.         **********************************************************************/
  134.  
  135.        /**
  136.          * Return an iterator that iterates over all of the elements on the
  137.          * priority queue in descending order.
  138.          * <p>
  139.          * The iterator doesn't implement <tt>remove()</tt> since it's optional.
  140.          */
  141.         public Iterator<Integer> iterator() { return new HeapIterator(); }
  142.  
  143.         private class HeapIterator implements Iterator<Integer> {
  144.             // create a new pq
  145.             private IndexMaxPQ<Key> copy;
  146.  
  147.             // add all elements to copy of heap
  148.             // takes linear time since already in heap order so no keys move
  149.             public HeapIterator() {
  150.                 copy = new IndexMaxPQ<Key>(pq.length - 1);
  151.                 for (int i = 1; i <= N; i++)
  152.                     copy.insert(pq[i], keys[pq[i]]);
  153.             }
  154.  
  155.             public boolean hasNext()  { return !copy.isEmpty();                     }
  156.             public void remove()      { throw new UnsupportedOperationException();  }
  157.  
  158.             public Integer next() {
  159.                 if (!hasNext()) throw new NoSuchElementException();
  160.                 return copy.delMax();
  161.             }
  162.         }
  163.     }
  164.  
  165.  
  166.     private class IndexMinPQ<Key extends Comparable<Key>> implements Iterable<Integer> {
  167.         private int NMAX;        // maximum number of elements on PQ
  168.         private int N;           // number of elements on PQ
  169.         private int[] pq;        // binary heap using 1-based indexing
  170.         private int[] qp;        // inverse of pq - qp[pq[i]] = pq[qp[i]] = i
  171.         private Key[] keys;      // keys[i] = priority of i
  172.  
  173.        /**
  174.          * Create an empty indexed priority queue with indices between 0 and NMAX-1.
  175.          * @throws java.lang.IllegalArgumentException if NMAX < 0
  176.          */
  177.         public IndexMinPQ(int NMAX) {
  178.             if (NMAX < 0) throw new IllegalArgumentException();
  179.             this.NMAX = NMAX;
  180.             keys = (Key[]) new Comparable[NMAX + 1];    // make this of length NMAX??
  181.             pq   = new int[NMAX + 1];
  182.             qp   = new int[NMAX + 1];                   // make this of length NMAX??
  183.             for (int i = 0; i <= NMAX; i++) qp[i] = -1;
  184.         }
  185.  
  186.        /**
  187.          * Is the priority queue empty?
  188.          */
  189.         public boolean isEmpty() { return N == 0; }
  190.  
  191.        /**
  192.          * Is i an index on the priority queue?
  193.          * @throws java.lang.IndexOutOfBoundsException unless (0 &le; i < NMAX)
  194.          */
  195.         public boolean contains(int i) {
  196.             if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
  197.             return qp[i] != -1;
  198.         }
  199.  
  200.        /**
  201.          * Return the number of keys on the priority queue.
  202.          */
  203.         public int size() {
  204.             return N;
  205.         }
  206.  
  207.        /**
  208.          * Associate key with index i.
  209.          * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
  210.          * @throws java.util.IllegalArgumentException if there already is an item associated with index i.
  211.          */
  212.         public void insert(int i, Key key) {
  213.             if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
  214.             if (contains(i)) throw new IllegalArgumentException("index is already in the priority queue");
  215.             N++;
  216.             qp[i] = N;
  217.             pq[N] = i;
  218.             keys[i] = key;
  219.             swim(N);
  220.         }
  221.  
  222.        /**
  223.          * Return a minimal key.
  224.          * @throws java.util.NoSuchElementException if priority queue is empty.
  225.          */
  226.         public Key minKey() {
  227.             if (N == 0) throw new NoSuchElementException("Priority queue underflow");
  228.             return keys[pq[1]];        
  229.         }
  230.  
  231.        /**
  232.          * Delete a minimal key and return its associated index.
  233.          * @throws java.util.NoSuchElementException if priority queue is empty.
  234.          */
  235.         public int delMin() {
  236.             if (N == 0) throw new NoSuchElementException("Priority queue underflow");
  237.             int min = pq[1];        
  238.             exch(1, N--);
  239.             sink(1);
  240.             qp[min] = -1;            // delete
  241.             keys[pq[N+1]] = null;    // to help with garbage collection
  242.             pq[N+1] = -1;            // not needed
  243.             return min;
  244.         }
  245.        
  246.        /**
  247.          * Delete the key associated with index i.
  248.          * @throws java.lang.IndexOutOfBoundsException unless 0 &le; i < NMAX
  249.          * @throws java.util.NoSuchElementException no key is associated with index i
  250.          */
  251.         public void delete(int i) {
  252.             if (i < 0 || i >= NMAX) throw new IndexOutOfBoundsException();
  253.             if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
  254.             int index = qp[i];
  255.             exch(index, N--);
  256.             swim(index);
  257.             sink(index);
  258.             keys[i] = null;
  259.             qp[i] = -1;
  260.         }
  261.  
  262.  
  263.        /**************************************************************
  264.         * General helper functions
  265.         **************************************************************/
  266.         private boolean greater(int i, int j) {
  267.             return keys[pq[i]].compareTo(keys[pq[j]]) > 0;
  268.         }
  269.  
  270.         private void exch(int i, int j) {
  271.             int swap = pq[i]; pq[i] = pq[j]; pq[j] = swap;
  272.             qp[pq[i]] = i; qp[pq[j]] = j;
  273.         }
  274.  
  275.  
  276.        /**************************************************************
  277.         * Heap helper functions
  278.         **************************************************************/
  279.         private void swim(int k)  {
  280.             while (k > 1 && greater(k/2, k)) {
  281.                 exch(k, k/2);
  282.                 k = k/2;
  283.             }
  284.         }
  285.  
  286.         private void sink(int k) {
  287.             while (2*k <= N) {
  288.                 int j = 2*k;
  289.                 if (j < N && greater(j, j+1)) j++;
  290.                 if (!greater(k, j)) break;
  291.                 exch(k, j);
  292.                 k = j;
  293.             }
  294.         }
  295.  
  296.  
  297.        /***********************************************************************
  298.         * Iterators
  299.         **********************************************************************/
  300.  
  301.        /**
  302.          * Return an iterator that iterates over all of the elements on the
  303.          * priority queue in ascending order.
  304.          * <p>
  305.          * The iterator doesn't implement <tt>remove()</tt> since it's optional.
  306.          */
  307.         public Iterator<Integer> iterator() { return new HeapIterator(); }
  308.  
  309.         private class HeapIterator implements Iterator<Integer> {
  310.             // create a new pq
  311.             private IndexMinPQ<Key> copy;
  312.  
  313.             // add all elements to copy of heap
  314.             // takes linear time since already in heap order so no keys move
  315.             public HeapIterator() {
  316.                 copy = new IndexMinPQ<Key>(pq.length - 1);
  317.                 for (int i = 1; i <= N; i++)
  318.                     copy.insert(pq[i], keys[pq[i]]);
  319.             }
  320.  
  321.             public boolean hasNext()  { return !copy.isEmpty();                     }
  322.             public void remove()      { throw new UnsupportedOperationException();  }
  323.  
  324.             public Integer next() {
  325.                 if (!hasNext()) throw new NoSuchElementException();
  326.                 return copy.delMin();
  327.             }
  328.         }
  329.     }
  330.    
  331.     public static void main(String[] args) {
  332.         Scanner in = new Scanner(System.in);
  333.     /*
  334.         try {
  335.             in = new Scanner(new File("C:\\Users\\kartik\\Downloads\\input01.txt"));
  336.         } catch (FileNotFoundException e) {
  337.             // TODO Auto-generated catch block
  338.             e.printStackTrace();
  339.         }
  340.      */    
  341.         int N = in.nextInt(), iMin = 0, iMax = 0;
  342.         Boolean exchange = false;
  343.         Median inst = new Median();
  344.         MinPQ = inst.new IndexMinPQ<Long>(5*N + 1);
  345.         MaxPQ = inst.new IndexMaxPQ<Long>(5*N + 1);
  346.        
  347.         for(int i=0; i<N; i++)  {
  348.             String op = in.next();
  349.             long x = in.nextLong();
  350.            
  351.         // handle the remove operation
  352.             if(op.equals("r"))  {
  353.                 if(indexMin.containsKey(x)) {
  354.                     int index = indexMin.get(x).first();
  355.                     removeFromMap(x, index, indexMin);
  356.                     MinPQ.delete(index);
  357.                     exchange = false;
  358.                     if(MinPQ.size() < MaxPQ.size()) {   // delete from MaxPQ and insert into MinPQ
  359.                         exchange = true;
  360.                         long key1 = MaxPQ.maxKey();
  361.                         int index1 = MaxPQ.delMax();
  362.                         removeFromMap(key1, index1, indexMax);
  363.                        
  364.                         MinPQ.insert(iMin, key1);
  365.                         addToMap(key1, iMin, indexMin);
  366.                         iMin++;
  367.                     }
  368.                 } else if(indexMax.containsKey(x))  {
  369.                     int index = indexMax.get(x).first();
  370.                     removeFromMap(x, index, indexMax);
  371.                     MaxPQ.delete(index);
  372.                     exchange = true;
  373.                     if(MinPQ.size() > MaxPQ.size() + 1) {   // delete from MinPQ and insert into MaxPQ
  374.                         exchange = false;
  375.                         long key1 = MinPQ.minKey();
  376.                         int index1 = MinPQ.delMin();
  377.                         removeFromMap(key1, index1, indexMin);
  378.                        
  379.                         MaxPQ.insert(iMax, key1);
  380.                         addToMap(key1, iMax, indexMax);
  381.                         iMax++;
  382.                     }
  383.                 } else  {
  384.                     System.out.println("Wrong!");
  385.                     continue;
  386.                 }
  387.             }
  388.         // handle the add operation
  389.             else if(op.equals("a")) {
  390.                 MinPQ.insert(iMin, x);
  391.                 addToMap(x, iMin, indexMin);
  392.                 iMin++;
  393.                 if(exchange)    {
  394.                     long key = MinPQ.minKey();
  395.                     int index = MinPQ.delMin();
  396.                     removeFromMap(key, index, indexMin);
  397.                     MaxPQ.insert(iMax, key);
  398.                     addToMap(key, iMax, indexMax);
  399.                     iMax++;
  400.                     exchange = false;
  401.                 } else  {
  402.                     exchange = true;
  403.                     if(!MaxPQ.isEmpty() && MaxPQ.maxKey() > MinPQ.minKey()) {
  404.                         long key1 = MaxPQ.maxKey();
  405.                         int index1 = MaxPQ.delMax();
  406.                         removeFromMap(key1, index1, indexMax);
  407.  
  408.                         long key = MinPQ.minKey();
  409.                         int index = MinPQ.delMin();
  410.                         removeFromMap(key, index, indexMin);
  411.                         MaxPQ.insert(iMax, key);
  412.                         addToMap(key, iMax, indexMax);
  413.                         iMax++;
  414.                        
  415.                         MinPQ.insert(iMin, key1);
  416.                         addToMap(key1, iMin, indexMin);
  417.                         iMin++;
  418.                     }
  419.                 }
  420.             }
  421.  
  422.             if(MinPQ.size() > MaxPQ.size()) {
  423.                 long result = MinPQ.minKey();
  424.                 System.out.println( result );
  425.             } else if(!MaxPQ.isEmpty()) {
  426.                 long result = MinPQ.minKey() + MaxPQ.maxKey();
  427.                 if(result % 2 == 0) {
  428.                     System.out.println( result / 2 );
  429.                 } else  {
  430.                     if(result == -1)
  431.                         System.out.println("-0.5");
  432.                     else
  433.                         System.out.println( String.valueOf(result / 2) + ".5" );
  434.                 }              
  435.             } else  {
  436.                 System.out.println("Wrong!");
  437.             }
  438.         }
  439.  
  440.     }
  441.    
  442.     static void addToMap(long key, int val, TreeMap<Long, TreeSet<Integer>> map)    {
  443.         if(map.containsKey(key))
  444.             map.get(key).add(val);
  445.         else    {
  446.             TreeSet<Integer> arg = new TreeSet<Integer>();
  447.             arg.add(val);
  448.             map.put(key, arg);
  449.         }
  450.     }
  451.    
  452.     static void removeFromMap(long key, int val, TreeMap<Long, TreeSet<Integer>> map)   {
  453.         TreeSet<Integer> arg = map.get(key);
  454.         arg.remove(val);
  455.         if(arg.isEmpty())
  456.             map.remove(key);
  457.     }
  458.    
  459.     private static TreeMap<Long, TreeSet<Integer>> indexMin = new TreeMap<Long, TreeSet<Integer>>();
  460.     private static TreeMap<Long, TreeSet<Integer>> indexMax = new TreeMap<Long, TreeSet<Integer>>();
  461.     private static IndexMinPQ<Long> MinPQ = null;
  462.     private static IndexMaxPQ<Long> MaxPQ = null;
  463. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement