提出 #9275971


ソースコード 拡げる

;; -*- 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
(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  "NOTE: cannot read -2^62"
  (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 brute (as)
  #>as
  (let ((n (length as)) res)
    (dotimes (pivot (+ 1 n))
      (let ((as (copy-seq as))
            (sum pivot))
        (loop for j below pivot
              do (setf (aref as j) (* -2 (aref as j))))
        (loop for j from (- pivot 1) downto 0
              unless (= j (- n 1))
              do (loop
                   (when (<= (aref as j) (aref as (+ j 1)))
                     (return))
                   (setf (aref as j) (* -2 (aref as j)))
                   (incf sum)))
        (loop for j from pivot below n
              unless (zerop j)
              do (loop
                   (when (<= (aref as (- j 1)) (aref as j))
                     (return))
                   (setf (aref as j) (* -2 (aref as j)))
                   (incf sum)))
        ;; #>as
        (push sum res)))
    (reverse res)))

(declaim (inline calc-capacity))
(defun calc-capacity (a next-a)
  (assert (<= a next-a))
  (let ((ratio (floor next-a a)))
    (ash (- (integer-length ratio) 1) -1)))

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (as (make-array n :element-type 'uint32)))
    (declare (uint32 n))
    (dotimes (i n)
      (setf (aref as i) (read-fixnum)))
    (labels
        ((build-cumul (as)
           (let (stack ; index . capacity
                 (cumul (make-array (+ n 1) :element-type 'uint62 :initial-element 0)))
             (push (cons (- n 1) #xffffffff) stack) ; sentinel
             (loop for i from (- n 2) downto 0
                   for next-a of-type uint32 = (aref as (+ i 1))
                   for new-value of-type uint62 = (aref cumul (+ i 1))
                   do (loop
                        (when (<= (aref as i) next-a)
                          (let ((cap (calc-capacity (aref as i) next-a)))
                            (when (> cap 0)
                              (push (cons i cap) stack)))
                          (return))
                        (setq next-a (* next-a 4))
                        (let ((node (car stack)))
                          (declare ((cons uint32 uint32) node))
                          (incf new-value (* 2 (- (car node) i)))
                          (decf (cdr node))
                          (when (zerop (cdr node))
                            (pop stack))))
                      (setf (aref cumul i) new-value))
             cumul)))
      (let ((cumul+ (build-cumul as))
            (cumul- (nreverse (build-cumul (nreverse as)))))
        ;; (dotimes (i (+ n 1))
        ;;   (incf (aref cumul- i) i))
        (println
         (loop for i to n
               minimize (+ (aref cumul+ i)
                           (aref cumul- i)
                           i)
               of-type uint62))))))

#-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:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" '("get-clipboard") :output out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :output out :search t)))

#+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 "200000~%")
    (dotimes (i 200000)
      (println (+ 1 (random 1000000000)) 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 "4
3 1 4 1
"
    "3
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "5
1 2 3 4 5
"
    "0
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "8
657312726 129662684 181537270 324043958 468214806 916875077 825989291 319670097
"
    "7
")))

提出情報

提出日時
問題 E - Negative Doubling
ユーザ sansaqua
言語 Common Lisp (SBCL 1.1.14)
得点 800
コード長 8024 Byte
結果 AC
実行時間 215 ms
メモリ 28772 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 800 / 800
結果
AC × 3
AC × 28
セット名 テストケース
Sample sample1.txt, sample2.txt, sample3.txt
All sample1.txt, sample2.txt, sample3.txt, 1.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 2.txt, 20.txt, 21.txt, 22.txt, 3.txt, 4.txt, 5.txt, 6.txt, 7.txt, 8.txt, 9.txt, sample1.txt, sample2.txt, sample3.txt
ケース名 結果 実行時間 メモリ
1.txt AC 215 ms 28772 KiB
10.txt AC 127 ms 18920 KiB
11.txt AC 126 ms 18912 KiB
12.txt AC 129 ms 20968 KiB
13.txt AC 129 ms 20960 KiB
14.txt AC 129 ms 20968 KiB
15.txt AC 130 ms 20960 KiB
16.txt AC 126 ms 18912 KiB
17.txt AC 126 ms 18912 KiB
18.txt AC 126 ms 18916 KiB
19.txt AC 123 ms 18916 KiB
2.txt AC 129 ms 20964 KiB
20.txt AC 126 ms 18916 KiB
21.txt AC 126 ms 18916 KiB
22.txt AC 126 ms 18912 KiB
3.txt AC 126 ms 18916 KiB
4.txt AC 126 ms 18916 KiB
5.txt AC 126 ms 18912 KiB
6.txt AC 131 ms 20964 KiB
7.txt AC 130 ms 20960 KiB
8.txt AC 124 ms 20964 KiB
9.txt AC 129 ms 20968 KiB
sample1.txt AC 75 ms 16872 KiB
sample2.txt AC 75 ms 16864 KiB
sample3.txt AC 75 ms 16872 KiB