Submission #6536941
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 (ql:quickload '(:cl-debug-print :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) #-swank (disable-debugger) ; for CS Academy ;; BEGIN_INSERTED_CONTENTS ;; Should we do this with UNWIND-PROTECT? (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))))) ;;; ;;; Disjoint set by Union-Find algorithm ;;; (defstruct (disjoint-set (:constructor make-disjoint-set (size &aux (data (make-array size :element-type 'fixnum :initial-element -1)))) (:conc-name ds-)) (data nil :type (simple-array fixnum (*)))) (declaim (ftype (function * (values (mod #.array-total-size-limit) &optional)) ds-root)) (defun ds-root (x disjoint-set) "Returns the root of X." (declare (optimize (speed 3) (safety 0)) ((mod #.array-total-size-limit) x)) (let ((data (ds-data disjoint-set))) (if (< (aref data x) 0) x (setf (aref data x) (ds-root (aref data x) disjoint-set))))) (declaim (inline ds-unite!)) (defun ds-unite! (x1 x2 disjoint-set) "Destructively unites X1 and X2 and returns true iff X1 and X2 become connected for the first time." (let ((root1 (ds-root x1 disjoint-set)) (root2 (ds-root x2 disjoint-set))) (unless (= root1 root2) (let ((data (ds-data disjoint-set))) ;; ensure the size of root1 >= the size of root2 (when (> (aref data root1) (aref data root2)) (rotatef root1 root2)) (incf (aref data root1) (aref data root2)) (setf (aref data root2) root1))))) (declaim (inline ds-connected-p)) (defun ds-connected-p (x1 x2 disjoint-set) "Returns true iff X1 and X2 have the same root." (= (ds-root x1 disjoint-set) (ds-root x2 disjoint-set))) (declaim (inline ds-size)) (defun ds-size (x disjoint-set) "Returns the size of the connected component to which X belongs." (- (aref (ds-data disjoint-set) (ds-root x disjoint-set)))) (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* ((result (loop (let ((byte (%read-byte))) (cond ((<= 48 byte 57) (return (- byte 48))) ((zerop byte) ; #\Nul (error "Read EOF or #\Nul."))))))) (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 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 (declaim (inline map-binsorted)) (defun map-binsorted (function sequence range-max &key from-end key) (declare ((mod #.array-total-size-limit) range-max)) (let ((counts (make-array (1+ range-max) :element-type 'list :initial-element nil)) (existing-min most-positive-fixnum) (existing-max 0)) (declare (dynamic-extent counts)) (sequence:dosequence (e sequence) (let ((key (funcall key e))) (push e (aref counts key)) (when (< key existing-min) (setf existing-min key)) (when (< existing-max key) (setf existing-max key)))) (if from-end (loop for v from existing-max downto existing-min do (dolist (e (aref counts v)) (funcall function e))) (loop for v from existing-min to existing-max do (dolist (e (aref counts v)) (funcall function e)))))) (defmacro do-binsorted ((var sequence range-max &key from-end key finally) &body body) "DO-style macro of MAP-BINSORTED" `(block nil (map-binsorted (lambda (,var) ,@body) ,sequence ,range-max :key ,key :from-end ,from-end) ,finally)) (defun main () (declare #.OPT (inline sort)) (let* ((n (read)) (m (read)) (adj (make-array (list n n) :element-type 'uint32 :initial-element #xffffffff)) (msts (make-array n :element-type 'list :initial-element nil)) (dset (make-disjoint-set n)) (buckets (make-array 100001 :element-type 'list))) (declare (uint31 n m)) (dotimes (i m) (let ((u (read-fixnum+)) (v (read-fixnum+)) (w (read-fixnum+))) (setf (aref adj u v) w (aref adj v u) w))) (with-buffered-stdout (dotimes (_ (the uint32 (read))) (let ((p (read-fixnum+)) (q (read-fixnum+)) pset qset edges new-edges (tmp-dset (make-disjoint-set n)) (res 0)) (declare (uint32 res)) (dotimes (i n) (when (ds-connected-p i p dset) (push i pset)) (when (ds-connected-p i q dset) (push i qset))) (dolist (v1 pset) (dolist (v2 qset) (unless (= #xffffffff (aref adj v1 v2)) (push (list* (aref adj v1 v2) v1 v2) edges)))) (dolist (e (aref msts p)) (push e edges)) (dolist (e (aref msts q)) (push e edges)) (dotimes (i (length buckets)) (setf (aref buckets i) nil)) (let ((existing-min most-positive-fixnum) (existing-max 0)) (dolist (e edges) (let ((cost (car e))) (push e (aref buckets cost)) (when (< cost existing-min) (setf existing-min cost)) (when (< existing-max cost) (setf existing-max cost)))) (loop for v from existing-min to existing-max do (dolist (node (aref buckets v)) (let ((cost (car node)) (edge (cdr node))) (unless (ds-connected-p (car edge) (cdr edge) tmp-dset) (ds-unite! (car edge) (cdr edge) tmp-dset) (push node new-edges) (incf res (the uint32 cost))))))) (if (= (+ (length pset) (length qset)) (ds-size p tmp-dset)) (println res) (write-line "IMPOSSIBLE")) (ds-unite! p q dset) (dolist (i pset) (setf (aref msts i) new-edges)) (dolist (i qset) (setf (aref msts i) new-edges))))))) #-swank (main)
Submission Info
Submission Time | |
---|---|
Task | F - 魔法の糸 |
User | sansaqua |
Language | Common Lisp (SBCL 1.1.14) |
Score | 200 |
Code Size | 8297 Byte |
Status | AC |
Exec Time | 840 ms |
Memory | 82660 KiB |
Judge Result
Set Name | All | ||
---|---|---|---|
Score / Max Score | 200 / 200 | ||
Status |
|
Set Name | Test Cases |
---|---|
All | 00-sample1, 00-sample2, 01-random-small-tree01, 01-random-small-tree02, 02-random-small-sparse01, 02-random-small-sparse02, 02-random-small-sparse03, 03-random-small-dense01, 03-random-small-dense02, 03-random-small-dense03, 03-random-small-dense04, 03-random-small-dense05, 11-random-large-tree01, 11-random-large-tree02, 11-random-large-tree03, 12-random-large-sparse01, 12-random-large-sparse02, 12-random-large-sparse03, 13-random-large-denseA01, 13-random-large-denseA02, 13-random-large-denseA03, 13-random-large-denseA04, 14-random-large-denseB01, 14-random-large-denseB02, 14-random-large-denseB03, 14-random-large-denseB04, 15-random-large-denseC01, 15-random-large-denseC02, 20-kill-naive, 21-kill-loop, 23-min |
Case Name | Status | Exec Time | Memory |
---|---|---|---|
00-sample1 | AC | 270 ms | 35816 KiB |
00-sample2 | AC | 114 ms | 23144 KiB |
01-random-small-tree01 | AC | 121 ms | 25188 KiB |
01-random-small-tree02 | AC | 122 ms | 25188 KiB |
02-random-small-sparse01 | AC | 121 ms | 25192 KiB |
02-random-small-sparse02 | AC | 121 ms | 25184 KiB |
02-random-small-sparse03 | AC | 122 ms | 25184 KiB |
03-random-small-dense01 | AC | 122 ms | 25188 KiB |
03-random-small-dense02 | AC | 122 ms | 25192 KiB |
03-random-small-dense03 | AC | 122 ms | 25188 KiB |
03-random-small-dense04 | AC | 122 ms | 25188 KiB |
03-random-small-dense05 | AC | 121 ms | 25188 KiB |
11-random-large-tree01 | AC | 674 ms | 80612 KiB |
11-random-large-tree02 | AC | 672 ms | 80612 KiB |
11-random-large-tree03 | AC | 666 ms | 80612 KiB |
12-random-large-sparse01 | AC | 705 ms | 80612 KiB |
12-random-large-sparse02 | AC | 707 ms | 80612 KiB |
12-random-large-sparse03 | AC | 711 ms | 80612 KiB |
13-random-large-denseA01 | AC | 823 ms | 80612 KiB |
13-random-large-denseA02 | AC | 825 ms | 80612 KiB |
13-random-large-denseA03 | AC | 831 ms | 80608 KiB |
13-random-large-denseA04 | AC | 840 ms | 80612 KiB |
14-random-large-denseB01 | AC | 590 ms | 82660 KiB |
14-random-large-denseB02 | AC | 583 ms | 80612 KiB |
14-random-large-denseB03 | AC | 592 ms | 80612 KiB |
14-random-large-denseB04 | AC | 584 ms | 80616 KiB |
15-random-large-denseC01 | AC | 569 ms | 80612 KiB |
15-random-large-denseC02 | AC | 568 ms | 80616 KiB |
20-kill-naive | AC | 612 ms | 80484 KiB |
21-kill-loop | AC | 631 ms | 82532 KiB |
23-min | AC | 113 ms | 23136 KiB |