Submission #6132285


Source Code Expand

;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam))
  #-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)

;; BEGIN_INSERTED_CONTENTS
;;;
;;; Binary heap
;;;

(define-condition heap-empty-error (simple-error)
  ((heap :initarg :heap :reader heap-empty-error-heap))
  (:report
   (lambda (condition stream)
     (format stream "Attempted to pop empty heap ~W" (heap-empty-error-heap condition)))))

(define-condition heap-full-error (simple-error)
  ((heap :initarg :heap :reader heap-full-error-heap)
   (item :initarg :item :reader heap-full-error-item))
  (:report
   (lambda (condition stream)
     (format stream "Attempted to push item ~W to full heap ~W"
             (heap-full-error-item condition)
             (heap-full-error-heap condition)))))

(defmacro define-binary-heap (name &key (order '#'>) (element-type 'fixnum))
  (check-type name symbol)
  (let* ((string-name (string name))
         (fname-push (intern (format nil "~A-PUSH" string-name)))
         (fname-pop (intern (format nil "~A-POP" string-name)))
         (fname-reinitialize (intern (format nil "~A-REINITIALIZE" string-name)))
         (fname-empty-p (intern (format nil "~A-EMPTY-P" string-name)))
         (fname-count (intern (format nil "~A-COUNT" string-name)))
         (fname-peak (intern (format nil "~A-PEAK" string-name)))
         (fname-make (intern (format nil "MAKE-~A" string-name)))
         (acc-position (intern (format nil "~A-POSITION" string-name)))
         (acc-data (intern (format nil "~A-DATA" string-name))))
    `(progn
       (defstruct (,name
                   (:constructor ,fname-make
                       (size
                        &aux (data ,(if (eql element-type '*)
                                        `(make-array (1+ size))
                                        `(make-array (1+ size) :element-type ',element-type))))))
         (data #() :type (simple-array ,element-type (*)) :read-only t)
         (position 1 :type (integer 1 #.most-positive-fixnum)))

       (declaim (sb-ext:maybe-inline ,fname-push))
       (defun ,fname-push (obj heap)
         "Adds OBJ to the end of HEAP."
         (declare (optimize (speed 3))
                  (type ,name heap))
         (symbol-macrolet ((position (,acc-position heap)))
           (let ((data (,acc-data heap)))
             (declare ((simple-array ,element-type (*)) data))
             (labels ((update (pos)
                        (declare (optimize (speed 3) (safety 0)))
                        (unless (= pos 1)
                          (let ((parent-pos (ash pos -1)))
                            (when (funcall ,order (aref data pos) (aref data parent-pos))
                              (rotatef (aref data pos) (aref data parent-pos))
                              (update parent-pos))))))
               (unless (< position (length data))
                 (error 'heap-full-error :heap heap :item obj))
               (setf (aref data position) obj)
               (update position)
               (incf position)
               heap))))
       (declaim (notinline ,fname-push))

       (declaim (sb-ext:maybe-inline ,fname-pop))
       (defun ,fname-pop (heap)
         "Pops an element from the top of HEAP."
         (declare (optimize (speed 3))
                  (type ,name heap))
         (symbol-macrolet ((position (,acc-position heap)))
           (let ((data (,acc-data heap)))
             (declare ((simple-array ,element-type (*)) data))
             (labels ((update (pos)
                        (declare (optimize (speed 3) (safety 0))
                                 ((integer 1 #.most-positive-fixnum) pos))
                        (let* ((child-pos1 (+ pos pos))
                               (child-pos2 (1+ child-pos1)))
                          (when (<= child-pos1 position)
                            (if (<= child-pos2 position)
                                (if (funcall ,order (aref data child-pos1) (aref data child-pos2))
                                    (unless (funcall ,order (aref data pos) (aref data child-pos1))
                                      (rotatef (aref data pos) (aref data child-pos1))
                                      (update child-pos1))
                                    (unless (funcall ,order (aref data pos) (aref data child-pos2))
                                      (rotatef (aref data pos) (aref data child-pos2))
                                      (update child-pos2)))
                                (unless (funcall ,order (aref data pos) (aref data child-pos1))
                                  (rotatef (aref data pos) (aref data child-pos1))))))))
               (when (= position 1)
                 (error 'heap-empty-error :heap heap))
               (prog1 (aref data 1)
                 (decf position)
                 (setf (aref data 1) (aref data position))
                 (update 1))))))

       (declaim (inline ,fname-reinitialize))
       (defun ,fname-reinitialize (heap)
         "Makes HEAP empty."
         (setf (,acc-position heap) 1)
         heap)

       (declaim (inline ,fname-empty-p))
       (defun ,fname-empty-p (heap)
         "Returns true if HEAP is empty."
         (= 1 (,acc-position heap)))

       (declaim (inline ,fname-count))
       (defun ,fname-count (heap)
         "Returns the current number of the elements in HEAP."
         (- (,acc-position heap) 1))

       (declaim (inline ,fname-peak))
       (defun ,fname-peak (heap)
         "Returns the topmost element of HEAP."
         (if (= 1 (,acc-position heap))
             (error 'heap-empty-error :heap heap)
             (aref (,acc-data heap) 1))))))

;; unfinished.

(declaim (inline find-optimum))
(defun find-optimum (sequence predicate &key (start 0) end)
  "Returns an index x that satisfies (NOT (FUNCALL PREDICATE SEQUENCE[y]
SEQUENCE[x])) (i.e. SEQUENCE[x] >= SEQUENCE[y]) for all the indices y and
returns SEQUENCE[x] as the second value."
  (declare ((or null (integer 0 #.most-positive-fixnum)) end)
           ((integer 0 #.most-positive-fixnum) start)
           (function predicate)
           (sequence sequence))
  (etypecase sequence
    (list (error "Not implemented yet."))
    (vector
     (let ((end (or end (length sequence))))
       (unless (<= start end)
         (error "Can't find optimal value in null interval [~A, ~A)" start end))
       (let ((optimum (aref sequence 0))
             (index 0))
         (dotimes (i (length sequence) (values index optimum))
           (unless (funcall predicate optimum (aref sequence i))
             (setq optimum (aref sequence i)
                   index i))))))))

(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

(define-binary-heap heap
  :order #'<
  :element-type (unsigned-byte 32))

(define-binary-heap heapheap
  :order (lambda (h1 h2)
           (let ((min1 (heap-peak h1))
                 (min2 (heap-peak h2)))
             (declare (uint32 min1 min2))
             (< min1 min2)))
  :element-type heap)

(defun cut-seq (as k)
  (declare #.OPT
           ((simple-array uint32 (*)) as)
           (uint32 k))
  (let ((qqueue (make-heapheap (length as)))
        (base (position #xffffffff as :test (complement #'eql))))
    (loop for i from base below (length as)
          do (when (= #xffffffff (aref as i))
               (when (>= (- i base) k)
                 (let ((queue (make-heap (- i base))))
                   (loop for j from base below i
                         do (heap-push (aref as j) queue))
                   (heapheap-push queue qqueue)))
               (setq base (+ i 1))))
    qqueue))

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (k (read))
         (q (read))
         (as (make-array (+ n 1) :element-type 'uint32 :initial-element #xffffffff))
         (res #xffffffff))
    (declare (uint32 res n k q))
    (dotimes (i n) (setf (aref as i) (read-fixnum)))
    (dotimes (_ n)
      (let ((qqueue (cut-seq as k))
            (min #xffffffff)
            (max 0))
        (declare (uint32 min max))
        (dotimes (_ q (setf res (min res (- max min))))
          (when (heapheap-empty-p qqueue)
            (return))
          (let* ((teil (heapheap-pop qqueue))
                 (a (heap-pop teil)))
            (declare (uint32 a))
            (setf min (min a min)
                  max (max a max))
            (when (>= (heap-count teil) k)
              (heapheap-push teil qqueue))))
        (setf (aref as (find-optimum as #'<)) #xffffffff)))
    (println res)))

#-swank(main)

Submission Info

Submission Time
Task E - Range Minimum Queries
User sansaqua
Language Common Lisp (SBCL 1.1.14)
Score 600
Code Size 10976 Byte
Status AC
Exec Time 403 ms
Memory 70376 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 600 / 600
Status
AC × 3
AC × 54
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All sample_01.txt, sample_02.txt, sample_03.txt, sample_01.txt, sample_02.txt, sample_03.txt, subtask_1_01.txt, subtask_1_02.txt, subtask_1_03.txt, subtask_1_04.txt, subtask_1_05.txt, subtask_1_06.txt, subtask_1_07.txt, subtask_1_08.txt, subtask_1_09.txt, subtask_1_10.txt, subtask_1_11.txt, subtask_1_12.txt, subtask_1_13.txt, subtask_1_14.txt, subtask_1_15.txt, subtask_1_16.txt, subtask_1_17.txt, subtask_1_18.txt, subtask_1_19.txt, subtask_1_20.txt, subtask_1_21.txt, subtask_1_22.txt, subtask_1_23.txt, subtask_1_24.txt, subtask_1_25.txt, subtask_1_26.txt, subtask_1_27.txt, subtask_1_28.txt, subtask_1_29.txt, subtask_1_30.txt, subtask_1_31.txt, subtask_1_32.txt, subtask_1_33.txt, subtask_1_34.txt, subtask_1_35.txt, subtask_1_36.txt, subtask_1_37.txt, subtask_1_38.txt, subtask_1_39.txt, subtask_1_40.txt, subtask_1_41.txt, subtask_1_42.txt, subtask_1_43.txt, subtask_1_44.txt, subtask_1_45.txt, subtask_1_46.txt, subtask_1_47.txt, subtask_1_48.txt
Case Name Status Exec Time Memory
sample_01.txt AC 203 ms 38500 KiB
sample_02.txt AC 192 ms 37604 KiB
sample_03.txt AC 191 ms 37604 KiB
subtask_1_01.txt AC 190 ms 37600 KiB
subtask_1_02.txt AC 189 ms 37604 KiB
subtask_1_03.txt AC 291 ms 64360 KiB
subtask_1_04.txt AC 191 ms 37604 KiB
subtask_1_05.txt AC 198 ms 37604 KiB
subtask_1_06.txt AC 194 ms 39648 KiB
subtask_1_07.txt AC 216 ms 64232 KiB
subtask_1_08.txt AC 235 ms 62176 KiB
subtask_1_09.txt AC 269 ms 60128 KiB
subtask_1_10.txt AC 234 ms 56040 KiB
subtask_1_11.txt AC 257 ms 68320 KiB
subtask_1_12.txt AC 260 ms 60136 KiB
subtask_1_13.txt AC 394 ms 60132 KiB
subtask_1_14.txt AC 239 ms 64228 KiB
subtask_1_15.txt AC 228 ms 64224 KiB
subtask_1_16.txt AC 254 ms 66276 KiB
subtask_1_17.txt AC 403 ms 68324 KiB
subtask_1_18.txt AC 257 ms 68320 KiB
subtask_1_19.txt AC 285 ms 68324 KiB
subtask_1_20.txt AC 237 ms 68320 KiB
subtask_1_21.txt AC 259 ms 68324 KiB
subtask_1_22.txt AC 402 ms 68328 KiB
subtask_1_23.txt AC 258 ms 68320 KiB
subtask_1_24.txt AC 261 ms 60132 KiB
subtask_1_25.txt AC 373 ms 60136 KiB
subtask_1_26.txt AC 235 ms 66276 KiB
subtask_1_27.txt AC 235 ms 70376 KiB
subtask_1_28.txt AC 246 ms 64224 KiB
subtask_1_29.txt AC 380 ms 68324 KiB
subtask_1_30.txt AC 299 ms 68328 KiB
subtask_1_31.txt AC 250 ms 64232 KiB
subtask_1_32.txt AC 229 ms 66272 KiB
subtask_1_33.txt AC 216 ms 60128 KiB
subtask_1_34.txt AC 215 ms 60132 KiB
subtask_1_35.txt AC 215 ms 60128 KiB
subtask_1_36.txt AC 218 ms 60132 KiB
subtask_1_37.txt AC 257 ms 64232 KiB
subtask_1_38.txt AC 212 ms 60132 KiB
subtask_1_39.txt AC 224 ms 62180 KiB
subtask_1_40.txt AC 281 ms 70376 KiB
subtask_1_41.txt AC 217 ms 60136 KiB
subtask_1_42.txt AC 218 ms 60136 KiB
subtask_1_43.txt AC 217 ms 60132 KiB
subtask_1_44.txt AC 219 ms 60128 KiB
subtask_1_45.txt AC 295 ms 68320 KiB
subtask_1_46.txt AC 242 ms 68324 KiB
subtask_1_47.txt AC 219 ms 60132 KiB
subtask_1_48.txt AC 215 ms 60132 KiB