Submission #10331957
Source Code Expand
(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
(defmacro with-buffered-stdout (&body body)
"Buffers all outputs to *STANDARD-OUTPUT* in BODY and flushes them to
*STANDARD-OUTPUT* after BODY has been done (without error). Note that only
BASE-CHAR is allowed."
(let ((out (gensym)))
`(let ((,out (make-string-output-stream :element-type 'base-char)))
(let ((*standard-output* ,out))
,@body)
(write-string (get-output-stream-string ,out)))))
(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))))))))
;;;
;;; Binary heap
;;;
(define-condition heap-empty-error (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)))))
(defmacro define-binary-heap (name &key (order '#'>) (element-type 'fixnum))
"Defines a binary heap specialized for the given order and the element
type. This macro defines a structure of the name NAME and relevant functions:
MAKE-<NAME>, <NAME>-PUSH, <NAME>-POP, <NAME>-REINITIALIZE, <NAME>-EMPTY-P,
<NAME>-COUNT, and <NAME>-PEEK."
(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-peek (intern (format nil "~A-PEEK" 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
(locally
;; prevent style warnings
(declare #+sbcl (muffle-conditions style-warning))
(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 (*)))
(position 1 :type (integer 1 #.most-positive-fixnum))))
(declaim #+sbcl (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)))
(when (>= position (length (,acc-data heap)))
(setf (,acc-data heap)
(adjust-array (,acc-data heap)
(min (- array-total-size-limit 1)
(* position 2)))))
(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))))))
(setf (aref data position) obj)
(update position)
(incf position)
heap))))
(declaim #+sbcl (sb-ext:maybe-inline ,fname-pop))
(defun ,fname-pop (heap)
"Removes and returns the element at 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 iff 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-peek))
(defun ,fname-peek (heap)
"Returns the topmost element of HEAP."
(if (= 1 (,acc-position heap))
(error 'heap-empty-error :heap heap)
(aref (,acc-data heap) 1))))))
(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
;;;
;; day . duration
(define-binary-heap heap
:order (lambda (node1 node2)
(declare ((cons uint31 uint31) node1 node2))
(< (+ (car node1) (cdr node1))
(+ (car node2) (cdr node2))))
:element-type (cons uint31 uint31))
(defstruct (t1queue (:constructor make-t1queue
(size &aux (heap (make-heap size)))))
(sum 0 :type (integer 0 #.most-positive-fixnum))
(heap nil :type heap))
(declaim (inline t1queue-push))
(defun t1queue-push (obj t1queue)
(heap-push obj (t1queue-heap t1queue))
t1queue)
(declaim (inline t1queue-pop))
(defun t1queue-pop (t1queue)
(destructuring-bind (init-day . dur) (heap-pop (t1queue-heap t1queue))
(declare (ignore init-day))
(decf (t1queue-sum t1queue) dur)
t1queue))
(declaim (inline t1queue-peek))
(defun t1queue-peek (t1queue)
(heap-peek (t1queue-heap t1queue)))
(declaim (inline t1queue-step))
(defun t1queue-step (t1queue)
(incf (t1queue-sum t1queue)
(heap-count (t1queue-heap t1queue))))
(declaim (inline t1queue-empty-p))
(defun t1queue-empty-p (t1queue)
(heap-empty-p (t1queue-heap t1queue)))
(defstruct (t2queue (:constructor make-t2queue
(size &aux (heap (make-heap size)))))
(sum 0 :type (integer 0 #.most-positive-fixnum))
(increment 0 :type fixnum)
(heap nil :type heap))
(declaim (inline t2queue-push))
(defun t2queue-push (obj t2queue)
(heap-push obj (t2queue-heap t2queue))
(decf (t2queue-increment t2queue)) ;; -1からスタートして、stepで長さ*2を足す
t2queue)
(declaim (inline t2queue-pop))
(defun t2queue-pop (t2queue)
(destructuring-bind (init-day . dur) (heap-pop (t2queue-heap t2queue))
(declare (ignore init-day))
(decf (t2queue-increment t2queue) (- (* dur 2) 1))
(decf (t2queue-sum t2queue) (* dur dur))
t2queue))
(declaim (inline t2queue-peek))
(defun t2queue-peek (t2queue)
(heap-peek (t2queue-heap t2queue)))
(declaim (inline t2queue-step))
(defun t2queue-step (t2queue)
(incf (t2queue-increment t2queue)
(* 2 (heap-count (t2queue-heap t2queue))))
(incf (t2queue-sum t2queue)
(t2queue-increment t2queue)))
(declaim (inline t2queue-empty-p))
(defun t2queue-empty-p (t2queue)
(heap-empty-p (t2queue-heap t2queue)))
(defconstant +inf+ most-positive-fixnum)
(defun main ()
(let* ((n (read))
(q (read))
(ws (make-array n :element-type 'uint62))
(ts (make-array n :element-type 'uint8))
(xs (make-array n :element-type 'uint31))
(restored-day (make-array n :element-type 'int32 :initial-element -1))
(res (make-array 3652426 :element-type 'uint62))
(t0queue (make-heap n))
(t1queue (make-t1queue n))
(t2queue (make-t2queue n))
(score 0))
(dotimes (i n)
(setf (aref ws i) (read-fixnum)
(aref ts i) (read-fixnum)
(aref xs i) (read-fixnum)))
(let ((wpos 0))
(dotimes (day (length res))
;; 今日のスコアを記録する
(setf (aref res day) score)
;; 期限切れのサービスを消す
(loop (when (heap-empty-p t0queue)
(return))
(destructuring-bind (init-day . dur) (heap-peek t0queue)
(unless (= (+ init-day dur) day)
(return))
(heap-pop t0queue)))
(loop (when (t1queue-empty-p t1queue)
(return))
(destructuring-bind (init-day . dur) (t1queue-peek t1queue)
(unless (= (+ init-day dur) day)
(return))
(t1queue-pop t1queue)))
(loop (when (t2queue-empty-p t2queue)
(return))
(destructuring-bind (init-day . dur) (t2queue-peek t2queue)
(unless (= (+ init-day dur) day)
(return))
(t2queue-pop t2queue)))
;; 今日復旧したサービスを加える
(loop (when (= wpos n) (return))
(let ((w (aref ws wpos))
(type (aref ts wpos))
(x (aref xs wpos)))
(unless (>= score w)
(return))
(setf (aref restored-day wpos) day)
(ecase type
(0 (heap-push (cons day x) t0queue))
(1 (t1queue-push (cons day x) t1queue))
(2 (t2queue-push (cons day x) t2queue)))
(incf wpos)))
;; 今日の分のスコアを更新する
(incf score)
(incf score (heap-count t0queue))
(t1queue-step t1queue)
(incf score (t1queue-sum t1queue))
(t2queue-step t2queue)
(incf score (t2queue-sum t2queue))))
(with-buffered-stdout
(sb-int:dovector (day restored-day)
(if (= -1 day)
(write-line "Many years later")
(println day)))
(dotimes (i q)
(let ((y (read-fixnum)))
(println (aref res y)))))))
#-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 "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 "")))
#+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 11
1 0 2
4 1 3
7 2 4
0
1
2
3
4
5
6
7
8
9
10
"
"1
3
4
0
1
3
5
7
11
19
29
46
47
48
"))
(it.bese.fiveam:is
(common-lisp-user::io-equal "5 5
10000 0 20
10000 1 30
10000 0 40
10000 2 70
30000 2 10000
5000
10000
15000
20000
25000
"
"10000
10000
10000
10000
10039
5000
10000
40711690801
329498273301
333383477320
"))
(5am:is
(io-equal "2 2
3652425 0 1
3652426 2 10000
3652424
3652425
"
"3652425
Many years later
3652424
3652425
")))
Submission Info
Submission Time |
|
Task |
F - Acceleration of Network |
User |
sansaqua |
Language |
Common Lisp (SBCL 1.1.14) |
Score |
100 |
Code Size |
16578 Byte |
Status |
AC |
Exec Time |
445 ms |
Memory |
79328 KiB |
Judge Result
Set Name |
Partial 1 |
All |
Score / Max Score |
15 / 15 |
85 / 85 |
Status |
|
|
Set Name |
Test Cases |
Partial 1 |
0_00_sample_00, 0_10_Random_00_000000_000265, 0_10_Random_01_001000_000265, 0_10_Random_02_001000_000263, 0_10_Random_03_000003_000251, 0_10_Random_04_000003_000261, 0_10_Random_05_000003_000257, 0_10_Random_06_000009_000251, 0_10_Random_07_000000_000262, 0_10_Random_08_000000_000256, 0_10_Random_09_000003_000262, 0_10_Random_10_000002_000261, 0_10_Random_11_000006_000255, 0_10_Random_12_000004_000253, 0_10_Random_13_000054_000262, 0_10_Random_14_000033_000265, 0_10_Random_15_000052_000253, 0_10_Random_16_000000_000259, 0_10_Random_17_000078_000253, 0_10_Random_18_000417_000254, 0_10_Random_19_000417_000254, 0_10_Random_20_000913_000259, 0_10_Random_21_000238_000255, 0_10_Random_22_000335_000255 |
All |
0_00_sample_00, 0_10_Random_00_000000_000265, 0_10_Random_01_001000_000265, 0_10_Random_02_001000_000263, 0_10_Random_03_000003_000251, 0_10_Random_04_000003_000261, 0_10_Random_05_000003_000257, 0_10_Random_06_000009_000251, 0_10_Random_07_000000_000262, 0_10_Random_08_000000_000256, 0_10_Random_09_000003_000262, 0_10_Random_10_000002_000261, 0_10_Random_11_000006_000255, 0_10_Random_12_000004_000253, 0_10_Random_13_000054_000262, 0_10_Random_14_000033_000265, 0_10_Random_15_000052_000253, 0_10_Random_16_000000_000259, 0_10_Random_17_000078_000253, 0_10_Random_18_000417_000254, 0_10_Random_19_000417_000254, 0_10_Random_20_000913_000259, 0_10_Random_21_000238_000255, 0_10_Random_22_000335_000255, 1_00_sample_01, 1_00_sample_02, 1_01_Teuchi_00, 1_01_Teuchi_01, 1_01_Teuchi_02, 1_01_Teuchi_03, 1_10_Random_23_086198_063414, 1_10_Random_24_041759_025278, 1_10_Random_25_078163_017646, 1_10_Random_26_082466_052832, 1_10_Random_27_069483_058001, 1_10_Random_28_037260_074459, 1_10_Random_29_094251_071690, 1_10_Random_30_080555_029493, 1_10_Random_31_099897_068369, 1_10_Random_32_086928_020563, 1_10_Random_33_019288_027448, 1_10_Random_34_027325_013687, 1_10_Random_35_037565_046230, 1_10_Random_36_053110_007707, 1_10_Random_37_006561_051152, 1_10_Random_38_001724_008865, 1_10_Random_39_075823_030498, 1_10_Random_40_035920_003446, 1_10_Random_41_061129_090693, 1_10_Random_42_026102_061986, 1_20_HalfRandom_00_033145_012808, 1_20_HalfRandom_01_051361_052902, 1_20_HalfRandom_02_072789_061928, 1_20_HalfRandom_03_080965_031006, 1_20_HalfRandom_04_039937_038308, 1_20_HalfRandom_05_098476_067390, 1_20_HalfRandom_06_061198_009066, 1_20_HalfRandom_07_096374_098697, 1_20_HalfRandom_08_077042_019386, 1_20_HalfRandom_09_023570_047790 |
Case Name |
Status |
Exec Time |
Memory |
0_00_sample_00 |
AC |
390 ms |
79328 KiB |
0_10_Random_00_000000_000265 |
AC |
248 ms |
68324 KiB |
0_10_Random_01_001000_000265 |
AC |
268 ms |
72544 KiB |
0_10_Random_02_001000_000263 |
AC |
264 ms |
72420 KiB |
0_10_Random_03_000003_000251 |
AC |
248 ms |
68320 KiB |
0_10_Random_04_000003_000261 |
AC |
248 ms |
68328 KiB |
0_10_Random_05_000003_000257 |
AC |
248 ms |
68324 KiB |
0_10_Random_06_000009_000251 |
AC |
248 ms |
68324 KiB |
0_10_Random_07_000000_000262 |
AC |
248 ms |
68324 KiB |
0_10_Random_08_000000_000256 |
AC |
248 ms |
68324 KiB |
0_10_Random_09_000003_000262 |
AC |
248 ms |
68328 KiB |
0_10_Random_10_000002_000261 |
AC |
248 ms |
68324 KiB |
0_10_Random_11_000006_000255 |
AC |
248 ms |
68324 KiB |
0_10_Random_12_000004_000253 |
AC |
248 ms |
68324 KiB |
0_10_Random_13_000054_000262 |
AC |
248 ms |
68328 KiB |
0_10_Random_14_000033_000265 |
AC |
248 ms |
68324 KiB |
0_10_Random_15_000052_000253 |
AC |
248 ms |
68324 KiB |
0_10_Random_16_000000_000259 |
AC |
248 ms |
68324 KiB |
0_10_Random_17_000078_000253 |
AC |
248 ms |
68328 KiB |
0_10_Random_18_000417_000254 |
AC |
256 ms |
72420 KiB |
0_10_Random_19_000417_000254 |
AC |
257 ms |
72416 KiB |
0_10_Random_20_000913_000259 |
AC |
265 ms |
72416 KiB |
0_10_Random_21_000238_000255 |
AC |
257 ms |
72420 KiB |
0_10_Random_22_000335_000255 |
AC |
258 ms |
72420 KiB |
1_00_sample_01 |
AC |
248 ms |
68324 KiB |
1_00_sample_02 |
AC |
269 ms |
68324 KiB |
1_01_Teuchi_00 |
AC |
362 ms |
75236 KiB |
1_01_Teuchi_01 |
AC |
316 ms |
74596 KiB |
1_01_Teuchi_02 |
AC |
248 ms |
68324 KiB |
1_01_Teuchi_03 |
AC |
337 ms |
74596 KiB |
1_10_Random_23_086198_063414 |
AC |
395 ms |
75616 KiB |
1_10_Random_24_041759_025278 |
AC |
345 ms |
72936 KiB |
1_10_Random_25_078163_017646 |
AC |
334 ms |
74980 KiB |
1_10_Random_26_082466_052832 |
AC |
383 ms |
75488 KiB |
1_10_Random_27_069483_058001 |
AC |
372 ms |
75488 KiB |
1_10_Random_28_037260_074459 |
AC |
364 ms |
73696 KiB |
1_10_Random_29_094251_071690 |
AC |
401 ms |
75748 KiB |
1_10_Random_30_080555_029493 |
AC |
354 ms |
75108 KiB |
1_10_Random_31_099897_068369 |
AC |
414 ms |
75876 KiB |
1_10_Random_32_086928_020563 |
AC |
349 ms |
74980 KiB |
1_10_Random_33_019288_027448 |
AC |
303 ms |
72932 KiB |
1_10_Random_34_027325_013687 |
AC |
294 ms |
72804 KiB |
1_10_Random_35_037565_046230 |
AC |
336 ms |
73316 KiB |
1_10_Random_36_053110_007707 |
AC |
316 ms |
72804 KiB |
1_10_Random_37_006561_051152 |
AC |
312 ms |
73188 KiB |
1_10_Random_38_001724_008865 |
AC |
267 ms |
72544 KiB |
1_10_Random_39_075823_030498 |
AC |
362 ms |
75368 KiB |
1_10_Random_40_035920_003446 |
AC |
295 ms |
72676 KiB |
1_10_Random_41_061129_090693 |
AC |
407 ms |
76132 KiB |
1_10_Random_42_026102_061986 |
AC |
344 ms |
73444 KiB |
1_20_HalfRandom_00_033145_012808 |
AC |
321 ms |
72808 KiB |
1_20_HalfRandom_01_051361_052902 |
AC |
358 ms |
73448 KiB |
1_20_HalfRandom_02_072789_061928 |
AC |
394 ms |
75748 KiB |
1_20_HalfRandom_03_080965_031006 |
AC |
365 ms |
75620 KiB |
1_20_HalfRandom_04_039937_038308 |
AC |
343 ms |
73316 KiB |
1_20_HalfRandom_05_098476_067390 |
AC |
410 ms |
76260 KiB |
1_20_HalfRandom_06_061198_009066 |
AC |
329 ms |
75108 KiB |
1_20_HalfRandom_07_096374_098697 |
AC |
445 ms |
76768 KiB |
1_20_HalfRandom_08_077042_019386 |
AC |
350 ms |
75492 KiB |
1_20_HalfRandom_09_023570_047790 |
AC |
341 ms |
73316 KiB |