提出 #6535695


ソースコード 拡げる

;; -*- 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

(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)))
    (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))
          (setf edges (sort edges (lambda (x y) (< (the uint32 x) (the uint32 y)))
                            :key #'car))
          (dolist (node edges)
            (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)

提出情報

提出日時
問題 F - 魔法の糸
ユーザ sansaqua
言語 Common Lisp (SBCL 1.1.14)
得点 200
コード長 6578 Byte
結果 AC
実行時間 577 ms
メモリ 82664 KiB

ジャッジ結果

セット名 All
得点 / 配点 200 / 200
結果
AC × 31
セット名 テストケース
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
ケース名 結果 実行時間 メモリ
00-sample1 AC 320 ms 37984 KiB
00-sample2 AC 131 ms 25320 KiB
01-random-small-tree01 AC 132 ms 25316 KiB
01-random-small-tree02 AC 133 ms 27364 KiB
02-random-small-sparse01 AC 132 ms 27364 KiB
02-random-small-sparse02 AC 132 ms 27364 KiB
02-random-small-sparse03 AC 134 ms 27364 KiB
03-random-small-dense01 AC 132 ms 27360 KiB
03-random-small-dense02 AC 133 ms 27364 KiB
03-random-small-dense03 AC 132 ms 27364 KiB
03-random-small-dense04 AC 134 ms 27368 KiB
03-random-small-dense05 AC 134 ms 27360 KiB
11-random-large-tree01 AC 383 ms 82660 KiB
11-random-large-tree02 AC 387 ms 82656 KiB
11-random-large-tree03 AC 381 ms 82660 KiB
12-random-large-sparse01 AC 424 ms 82660 KiB
12-random-large-sparse02 AC 420 ms 82656 KiB
12-random-large-sparse03 AC 423 ms 82656 KiB
13-random-large-denseA01 AC 520 ms 82660 KiB
13-random-large-denseA02 AC 521 ms 82656 KiB
13-random-large-denseA03 AC 524 ms 82664 KiB
13-random-large-denseA04 AC 530 ms 82660 KiB
14-random-large-denseB01 AC 502 ms 80608 KiB
14-random-large-denseB02 AC 495 ms 82660 KiB
14-random-large-denseB03 AC 502 ms 82656 KiB
14-random-large-denseB04 AC 503 ms 80612 KiB
15-random-large-denseC01 AC 480 ms 80608 KiB
15-random-large-denseC02 AC 485 ms 82656 KiB
20-kill-naive AC 532 ms 82660 KiB
21-kill-loop AC 577 ms 82660 KiB
23-min AC 129 ms 25316 KiB