Problem:
Score : 600 points

Problem Statement

Snuke got an integer sequence of length N from his mother, as a birthday present. The i-th (1 ≦ i ≦ N) element of the sequence is a_i. The elements are pairwise distinct.
He is sorting this sequence in increasing order.
With supernatural power, he can perform the following two operations on the sequence in any order:

Operation 1: choose 2 consecutive elements, then reverse the order of those elements.

Operation 2: choose 3 consecutive elements, then reverse the order of those elements.

Snuke likes Operation 2, but not Operation 1. Find the minimum number of Operation 1 that he has to perform in order to sort the sequence in increasing order.

Constraints

1 ≦ N ≦ 10^5

0 ≦ A_i ≦ 10^9

If i ≠ j, then A_i ≠ A_j.

All input values are integers.

Input

The input is given from Standard Input in the following format:

N
A_1
:
A_N

Output

Print the minimum number of times Operation 1 that Snuke has to perform.

Sample Input 1

4
2
4
3
1

Sample Output 1

1

The given sequence can be sorted as follows:

First, reverse the order of the last three elements. The sequence is now: 2,1,3,4.

Then, reverse the order of the first two elements. The sequence is now: 1,2,3,4.

In this sequence of operations, Operation 1 is performed once. It is not possible to sort the sequence with less number of Operation 1, thus the answer is 1.

Sample Input 2

5
10
8
5
3
2

Sample Output 2

0

Solution in Common Lisp (SBCL 1.1.14) (judge verdict: Wrong Answer)

;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-int:defconstant-eqx OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0))
    #'equal)
  #+swank (ql:quickload '(:cl-debug-print :fiveam) :silent t)
  #-swank (set-dispatch-macro-character
           #\# #\> (lambda (s c p) (declare (ignore c p)) (read s nil (values) t))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
;;;
;;; ARRAY-ELEMENT-TYPE is not constant-folded on SBCL version earlier than
;;; 1.5.0. See
;;; https://github.com/sbcl/sbcl/commit/9f0d12e7ab961828931d01c0b2a76a5885ad35d2
;;;

(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-c:deftransform array-element-type ((array))
    (let ((type (sb-c::lvar-type array)))
      (flet ((element-type (type)
               (and (sb-c::array-type-p type)
                    (sb-int:neq (sb-kernel::array-type-specialized-element-type type) sb-kernel:*wild-type*)
                    (sb-kernel:type-specifier (sb-kernel::array-type-specialized-element-type type)))))
        (cond ((let ((type (element-type type)))
                 (and type
                      `',type)))
              ((sb-kernel:union-type-p type)
               (let (result)
                 (loop for type in (sb-kernel:union-type-types type)
                       for et = (element-type type)
                       unless (and et
                                   (if result
                                       (equal result et)
                                       (setf result et)))
                       do (sb-c::give-up-ir1-transform))
                 `',result))
              ((sb-kernel:intersection-type-p type)
               (loop for type in (sb-kernel:intersection-type-types type)
                     for et = (element-type type)
                     when et
                     return `',et
                     finally (sb-c::give-up-ir1-transform)))
              (t
               (sb-c::give-up-ir1-transform)))))))

;;;
;;; Compute inversion number by merge sort
;;;

(declaim (inline %merge-count))
(defun %merge-count (l mid r source-vec dest-vec predicate)
  (declare ((integer 0 #.array-total-size-limit) l mid r)
           (function predicate))
  (loop with count of-type (integer 0 #.most-positive-fixnum) = 0
        with i = l
        with j = mid
        for idx from l
        when (= i mid)
        do (loop for j from j below r
                 for idx from idx
                 do (setf (aref dest-vec idx)
                          (aref source-vec j))
                 finally (return-from %merge-count count))
        when (= j r)
        do (loop for i from i below mid
                 for idx from idx
                 do (setf (aref dest-vec idx)
                          (aref source-vec i))
                 finally (return-from %merge-count count))
        do (if (funcall predicate
                        (aref source-vec j)
                        (aref source-vec i))
               (setf (aref dest-vec idx) (aref source-vec j)
                     j (1+ j)
                     count (+ count (- mid i)))
               (setf (aref dest-vec idx) (aref source-vec i)
                     i (1+ i)))))

(defmacro with-fixnum+ (form)
  (let ((fixnum+ '(integer 0 #.most-positive-fixnum)))
    `(the ,fixnum+
          ,(reduce (lambda (f1 f2)`(,(car form)
                                   (the ,fixnum+ ,f1)
                                   (the ,fixnum+ ,f2)))
	           (cdr form)))))

(declaim (inline %calc-by-insertion-sort!))
(defun %calc-by-insertion-sort! (vec predicate l r)
  (declare (function predicate)
           ((integer 0 #.array-total-size-limit) l r))
  (loop with inv-count of-type (integer 0 #.most-positive-fixnum) = 0
        for end from (+ l 1) below r
        do (loop for i from end above l
                 while (funcall predicate (aref vec i) (aref vec (- i 1)))
                 do (rotatef (aref vec (- i 1)) (aref vec i))
                    (incf inv-count))
        finally (return inv-count)))

;; NOTE: This function is slow on SBCL version earlier than 1.5.0 as
;; constant-folding of ARRAY-ELEMENT-TYPE doesn't work. Use
;; array-element-type.lisp if necessary.
(declaim (inline calc-inversion-number!))
(defun calc-inversion-number! (vector predicate &key (start 0) end)
  "Calculates the inversion number of VECTOR w.r.t. the strict order
PREDICATE. This function sorts VECTOR as a side effect."
  (declare (vector vector)
           (function predicate))
  (let ((end (or end (length vector))))
    (declare ((integer 0 #.array-total-size-limit) start end))
    (assert (<= start end))
    (let ((buffer (make-array end :element-type (array-element-type vector))))
      (labels
          ((recur (l r merge-to-vec1-p)
             (declare (optimize (safety 0))
                      ((integer 0 #.array-total-size-limit) l r))
             (cond ((= l r) 0)
                   ((= (+ l 1) r)
                    (unless merge-to-vec1-p
                      (setf (aref buffer l) (aref vector l)))
                    0)
                   ;; It is faster to use insertion sort. I don't adopt it
                   ;; by default, however, because that makes it hard to
                   ;; change the code to fit some special settings.
                   ;; ((and (<= (- r l) 24) merge-to-vec1-p)
                   ;;  (%calc-by-insertion-sort! vector predicate l r))
                   (t
                    (let ((mid (floor (+ l r) 2)))
                      (with-fixnum+
                          (+ (recur l mid (not merge-to-vec1-p))
                             (recur mid r (not merge-to-vec1-p))
                             (if merge-to-vec1-p
                                 (%merge-count l mid r buffer vector predicate)
                                 (%merge-count l mid r vector buffer predicate)))))))))
        (recur start end t)))))

(declaim (inline bisect-left))
(defun bisect-left (target value &key (start 0) end (order #'<) (key #'identity))
  "TARGET := vector | function (taking an integer argument)
ORDER := strict order

Analogue of lower_bound of C++ or bisect_left of Python: Returns the smallest
index (or input) i that fulfills TARGET[i] >= VALUE, where '>=' is the
complement of ORDER. In other words, this function returns the leftmost index at
which VALUE can be inserted with keeping the order. Therefore, TARGET must be
monotonically non-decreasing with respect to ORDER.

This function returns END if VALUE exceeds TARGET[END-1]. Note that the range
[START, END) is half-open. END must be explicitly specified if TARGET is
function. KEY is applied to each element of TARGET before comparison."
  (declare (function key order)
           (integer start)
           ((or null integer) end))
  (macrolet
      ((body (accessor &optional declaration)
         `(progn
            (assert (<= start end))
            (if (= start end) end
                (labels
                    ((%bisect-left (left ok)
                       ;; TARGET[OK] >= VALUE always holds (assuming
                       ;; TARGET[END] = +infinity)
                       ,@(list declaration)
                       (let ((mid (ash (+ left ok) -1)))
                         (if (= mid left)
                             (if (funcall order (funcall key (,accessor target left)) value)
                                 ok
                                 left)
                             (if (funcall order (funcall key (,accessor target mid)) value)
                                 (%bisect-left mid ok)
                                 (%bisect-left left mid))))))
                  (%bisect-left start end))))))
    (etypecase target
      (vector
       (let ((end (or end (length target))))
         (body aref (declare ((integer 0 #.most-positive-fixnum) left ok)))))
      (function
       (assert end () "Requires END argument if TARGET is a function.")
       (body funcall)))))

(declaim (inline bisect-right))
(defun bisect-right (target value &key (start 0) end (order #'<) (key #'identity))
  "TARGET := vector | function (taking an integer argument)
ORDER := strict order

Analogue of upper_bound of C++ or bisect_right of Python: Returns the smallest
index (or input) i that fulfills TARGET[i] > VALUE. In other words, this
function returns the rightmost index at which VALUE can be inserted with keeping
the order. Therefore, TARGET must be monotonically non-decreasing with respect
to ORDER.

This function returns END if VALUE >= TARGET[END-1]. Note that the range [START,
END) is half-open. END must be explicitly specified if TARGET is function. KEY
is applied to each element of TARGET before comparison."
  (declare (function key order)
           (integer start)
           ((or null integer) end))
  (macrolet
      ((body (accessor &optional declaration)
         `(progn
            (assert (<= start end))
            (if (= start end)
                end
                (labels
                    ((%bisect-right (left ok)
                       ;; TARGET[OK] > VALUE always holds (assuming
                       ;; TARGET[END] = +infinity)
                       ,@(list declaration)
                       (let ((mid (ash (+ left ok) -1)))
                         (if (= mid left)
                             (if (funcall order value (funcall key (,accessor target left)))
                                 left
                                 ok)
                             (if (funcall order value (funcall key (,accessor target mid)))
                                 (%bisect-right left mid)
                                 (%bisect-right mid ok))))))
                  
                  (%bisect-right start end))))))
    (etypecase target
      (vector
       (when (null end)
         (setf end (length target)))
       (body aref (declare ((integer 0 #.most-positive-fixnum) left ok))))
      (function
       (assert end () "Requires END argument if TARGET is a function.")
       (body funcall)))))

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  (declare #.OPT)
  (macrolet ((%read-byte ()
               `(the (unsigned-byte 8)
                     #+swank (char-code (read-char in nil #\Nul))
                     #-swank (sb-impl::ansi-stream-read-byte in nil #.(char-code #\Nul) nil))))
    (let* ((minus nil)
           (result (loop (let ((byte (%read-byte)))
                           (cond ((<= 48 byte 57)
                                  (return (- byte 48)))
                                 ((zerop byte) ; #\Nul
                                  (error "Read EOF or #\Nul."))
                                 ((= byte #.(char-code #\-))
                                  (setf minus t)))))))
      (declare ((integer 0 #.most-positive-fixnum) result))
      (loop
        (let* ((byte (%read-byte)))
          (if (<= 48 byte 57)
              (setq result (+ (- byte 48) (* 10 (the (integer 0 #.(floor most-positive-fixnum 10)) result))))
              (return (if minus (- result) result))))))))

(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (declare (inline sort))
  (let* ((n (read))
         (as (make-array n :element-type 'uint32)))
    (declare (uint32 n))
    (dotimes (i n) (setf (aref as i) (read-fixnum)))
    (let ((sorted-as (sort (copy-seq as) #'<))
          (parities (make-array n :element-type 'bit :initial-element 0))
          (seq1 (make-array n :element-type 'uint32 :initial-element 0))
          (seq2 (make-array n :element-type 'uint32 :initial-element 0)))
      (dotimes (i n)
        (when (oddp (bisect-left sorted-as (aref as i)))
          (setf (aref parities i) 1)))
      (let ((index0 0)
            (index1 1))
        (dotimes (i n)
          (if (zerop (aref parities i))
              (progn (setf (aref seq1 i) index0)
                     (incf index0 2))
              (progn (setf (aref seq1 i) index1)
                     (incf index1 2)))))
      (let ((index0 1)
            (index1 0))
        (dotimes (i n)
          (if (zerop (aref parities i))
              (progn (setf (aref seq2 i) index0)
                     (incf index0 2))
              (progn (setf (aref seq2 i) index1)
                     (incf index1 2)))))
      (dbg seq1 seq2)
      (println (min (calc-inversion-number! seq1 #'<)
                    (if (evenp n)
                        (calc-inversion-number! seq2 #'<)
                        most-positive-fixnum))))))

#-swank (main)