Submission #8887897


Source Code Expand

;; -*- 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
           ;; enclose the form with VALUES to avoid being captured by LOOP macro
           #\# #\> (lambda (s c p) (declare (ignore c p)) `(values ,(read s nil nil t)))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
;;;
;;; Sort multiple vectors
;;;

;; Note: Not randomized; the worst case time complexity is O(n^2).

(declaim (inline %median3))
(defun %median3 (x y z order)
  (if (funcall order x y)
      (if (funcall order y z)
          y
          (if (funcall order z x)
              x
              z))
      (if (funcall order z y)
          y
          (if (funcall order x z)
              x
              z))))

(defun parallel-sort! (vector order &rest vectors)
  "Destructively sorts VECTOR w.r.t. ORDER and applies the same swappings to the
all vectors in VECTORS."
  (declare (vector vector))
  (labels
      ((recur (left right)
         (when (< left right)
           (let* ((l left)
                  (r right)
                  (pivot (%median3 (aref vector l)
                                   (aref vector (ash (+ l r) -1))
                                   (aref vector r)
                                   order)))
             (declare ((integer 0 #.most-positive-fixnum) l r))
             (loop (loop while (funcall order (aref vector l) pivot)
                         do (incf l 1))
                   (loop while (funcall order pivot (aref vector r))
                         do (decf r 1))
                   (when (>= l r)
                     (return))
                   (rotatef (aref vector l) (aref vector r))
                   (dolist (v vectors)
                     (rotatef (aref v l) (aref v r)))
                   (incf l 1)
                   (decf r 1))
             (recur left (- l 1))
             (recur (+ r 1) right)))))
    (recur 0 (- (length vector) 1))
    vector))

(sb-c:define-source-transform parallel-sort! (vector order &rest vectors)
  (let ((vec (gensym))
        (vecs (loop for _ in vectors collect (gensym))))
    `(let ((,vec ,vector)
           ,@(loop for v in vectors
                   for sym in vecs
                   collect `(,sym ,v)))
       (labels
           ((recur (left right)
              (when (< left right)
                (let* ((l left)
                       (r right)
                       (pivot (%median3 (aref ,vec l)
                                        (aref ,vec (ash (+ l r) -1))
                                        (aref ,vec r)
                                        ,order)))
                  (declare ((integer 0 #.most-positive-fixnum) l r))
                  (loop (loop while (funcall ,order (aref ,vec l) pivot)
                              do (incf l 1))
                        (loop while (funcall ,order pivot (aref ,vec r))
                              do (decf r 1))
                        (when (>= l r)
                          (return))
                        (rotatef (aref ,vec l) (aref ,vec r))
                        ,@(loop for sym in vecs
                                collect `(rotatef (aref ,sym l) (aref ,sym r)))
                        (incf l 1)
                        (decf r 1))
                  (recur left (- l 1))
                  (recur (+ r 1) right)))))
         (recur 0 (- (length ,vec) 1))
         ,vec))))

(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 #.OPT)
  (let* ((n (read))
         (as (make-array n :element-type 'uint62))
         (bs (make-array n :element-type 'uint62))
         (vs (make-array n :element-type 'fixnum)))
    (dotimes (i n)
      (let ((a (read-fixnum))
            (b (read-fixnum)))
        (setf (aref as i) a
              (aref bs i) b)))
    (parallel-sort! as #'< bs)
    (dotimes (i n)
      (setf (aref vs i)
            (- (aref bs i)
               (if (zerop i)
                   0
                   (- (aref as i)
                      (aref as (- i 1)))))))
    (let ((res most-negative-fixnum)
          (s 0))
      (declare (fixnum res s))
      (dotimes (i n)
        (setq s (max (+ s (aref vs i)) (aref bs i))
              res (max s res)))
      (println res))))

#-swank (main)

;;;
;;; Test and benchmark
;;;

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "C:/msys64/usr/bin/cat.exe" '("/dev/clipboard") :output out)))

#+swank (defparameter *this-pathname* (uiop:current-lisp-file-pathname))
#+swank (defparameter *dat-pathname* (uiop:merge-pathnames* "test.dat" *this-pathname*))

#+swank
(defun run (&optional thing (out *standard-output*))
  "THING := null | string | symbol | pathname

null: run #'MAIN using the text on clipboard as input.
string: run #'MAIN using the string as input.
symbol: alias of FIVEAM:RUN!.
pathname: run #'MAIN using the text file as input."
  (let ((*standard-output* out))
    (etypecase thing
      (null
       (with-input-from-string (*standard-input* (delete #\Return (get-clipbrd)))
         (main)))
      (string
       (with-input-from-string (*standard-input* (delete #\Return thing))
         (main)))
      (symbol (5am:run! thing))
      (pathname
       (with-open-file (*standard-input* thing)
         (main))))))

#+swank
(defun gen-dat ()
  (uiop:with-output-file (out *dat-pathname* :if-exists :supersede)
    (format out "")))

#+swank
(defun bench (&optional (out (make-broadcast-stream)))
  (time (run *dat-pathname* out)))

;; To run: (5am:run! :sample)
#+swank
(it.bese.fiveam:test :sample
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "3
2 3
11 2
4 5
"
    "6
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "6
4 1
1 5
10 3
9 1
4 2
5 3
"
    "7
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "15
1543361732 260774320
2089759661 257198921
1555665663 389548466
4133306295 296394520
2596448427 301103944
1701413087 274491541
2347488426 912791996
2133012079 444074242
2659886224 656957044
1345396764 259870638
2671164286 233246973
2791812672 585862344
2996614635 91065315
971304780 488995617
1523452673 988137562
"
    "4232545716
")))

Submission Info

Submission Time
Task B - 美術展 (Art Exhibition)
User sansaqua
Language Common Lisp (SBCL 1.1.14)
Score 100
Code Size 9197 Byte
Status AC
Exec Time 388 ms
Memory 29160 KiB

Judge Result

Set Name Sample Task1 Task2 Task3 Task4
Score / Max Score 0 / 0 10 / 10 20 / 20 30 / 30 40 / 40
Status
AC × 3
AC × 11
AC × 26
AC × 51
AC × 68
Set Name Test Cases
Sample sample-01.txt, sample-02.txt, sample-03.txt
Task1 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt
Task2 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt, 02-01.txt, 02-02.txt, 02-03.txt, 02-04.txt, 02-05.txt, 02-06.txt, 02-07.txt, 02-08.txt, 02-09.txt, 02-10.txt, 02-11.txt, 02-12.txt, 02-13.txt, 02-14.txt, 02-15.txt
Task3 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt, 02-01.txt, 02-02.txt, 02-03.txt, 02-04.txt, 02-05.txt, 02-06.txt, 02-07.txt, 02-08.txt, 02-09.txt, 02-10.txt, 02-11.txt, 02-12.txt, 02-13.txt, 02-14.txt, 02-15.txt, 03-01.txt, 03-02.txt, 03-03.txt, 03-04.txt, 03-05.txt, 03-06.txt, 03-07.txt, 03-08.txt, 03-09.txt, 03-10.txt, 03-11.txt, 03-12.txt, 03-13.txt, 03-14.txt, 03-15.txt, 03-16.txt, 03-17.txt, 03-18.txt, 03-19.txt, 03-20.txt, 03-21.txt, 03-22.txt, 03-23.txt, 03-24.txt, 03-25.txt
Task4 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt, 02-01.txt, 02-02.txt, 02-03.txt, 02-04.txt, 02-05.txt, 02-06.txt, 02-07.txt, 02-08.txt, 02-09.txt, 02-10.txt, 02-11.txt, 02-12.txt, 02-13.txt, 02-14.txt, 02-15.txt, 03-01.txt, 03-02.txt, 03-03.txt, 03-04.txt, 03-05.txt, 03-06.txt, 03-07.txt, 03-08.txt, 03-09.txt, 03-10.txt, 03-11.txt, 03-12.txt, 03-13.txt, 03-14.txt, 03-15.txt, 03-16.txt, 03-17.txt, 03-18.txt, 03-19.txt, 03-20.txt, 03-21.txt, 03-22.txt, 03-23.txt, 03-24.txt, 03-25.txt, 04-01.txt, 04-02.txt, 04-03.txt, 04-04.txt, 04-05.txt, 04-06.txt, 04-07.txt, 04-08.txt, 04-09.txt, 04-10.txt, 04-11.txt, 04-12.txt, 04-13.txt, 04-14.txt, 04-15.txt, 04-16.txt, 04-17.txt
Case Name Status Exec Time Memory
01-01.txt AC 270 ms 28520 KiB
01-02.txt AC 81 ms 16864 KiB
01-03.txt AC 77 ms 16872 KiB
01-04.txt AC 76 ms 16868 KiB
01-05.txt AC 76 ms 16872 KiB
01-06.txt AC 77 ms 16868 KiB
01-07.txt AC 77 ms 16868 KiB
01-08.txt AC 78 ms 16864 KiB
01-09.txt AC 80 ms 16872 KiB
01-10.txt AC 79 ms 16868 KiB
01-11.txt AC 77 ms 16868 KiB
02-01.txt AC 80 ms 16868 KiB
02-02.txt AC 79 ms 16864 KiB
02-03.txt AC 81 ms 16868 KiB
02-04.txt AC 77 ms 16872 KiB
02-05.txt AC 88 ms 16864 KiB
02-06.txt AC 77 ms 16872 KiB
02-07.txt AC 76 ms 16868 KiB
02-08.txt AC 77 ms 16872 KiB
02-09.txt AC 76 ms 16864 KiB
02-10.txt AC 77 ms 16864 KiB
02-11.txt AC 80 ms 16868 KiB
02-12.txt AC 81 ms 16868 KiB
02-13.txt AC 77 ms 16864 KiB
02-14.txt AC 79 ms 16864 KiB
02-15.txt AC 77 ms 16864 KiB
03-01.txt AC 79 ms 16868 KiB
03-02.txt AC 83 ms 16868 KiB
03-03.txt AC 84 ms 16868 KiB
03-04.txt AC 82 ms 16868 KiB
03-05.txt AC 82 ms 16868 KiB
03-06.txt AC 81 ms 16868 KiB
03-07.txt AC 81 ms 16868 KiB
03-08.txt AC 81 ms 16872 KiB
03-09.txt AC 81 ms 16872 KiB
03-10.txt AC 84 ms 16872 KiB
03-11.txt AC 83 ms 16872 KiB
03-12.txt AC 85 ms 16868 KiB
03-13.txt AC 84 ms 16868 KiB
03-14.txt AC 84 ms 16868 KiB
03-15.txt AC 83 ms 16868 KiB
03-16.txt AC 84 ms 16868 KiB
03-17.txt AC 82 ms 16864 KiB
03-18.txt AC 81 ms 16872 KiB
03-19.txt AC 79 ms 16864 KiB
03-20.txt AC 79 ms 16868 KiB
03-21.txt AC 79 ms 16868 KiB
03-22.txt AC 80 ms 16868 KiB
03-23.txt AC 83 ms 16868 KiB
03-24.txt AC 80 ms 16864 KiB
03-25.txt AC 79 ms 16868 KiB
04-01.txt AC 380 ms 29156 KiB
04-02.txt AC 384 ms 29156 KiB
04-03.txt AC 385 ms 29156 KiB
04-04.txt AC 385 ms 29156 KiB
04-05.txt AC 381 ms 29156 KiB
04-06.txt AC 382 ms 29160 KiB
04-07.txt AC 384 ms 29152 KiB
04-08.txt AC 385 ms 29156 KiB
04-09.txt AC 382 ms 29156 KiB
04-10.txt AC 376 ms 29152 KiB
04-11.txt AC 381 ms 29156 KiB
04-12.txt AC 380 ms 29156 KiB
04-13.txt AC 382 ms 29156 KiB
04-14.txt AC 383 ms 29156 KiB
04-15.txt AC 383 ms 29152 KiB
04-16.txt AC 385 ms 29156 KiB
04-17.txt AC 388 ms 29156 KiB
sample-01.txt AC 82 ms 16868 KiB
sample-02.txt AC 78 ms 16868 KiB
sample-03.txt AC 78 ms 16868 KiB