結果

問題 No.1750 ラムドスウイルスの感染拡大-hard
ユーザー motoshiramotoshira
提出日時 2021-11-21 22:50:51
言語 Common Lisp
(sbcl 2.3.8)
結果
WA  
実行時間 -
コード長 12,233 bytes
コンパイル時間 316 ms
コンパイル使用メモリ 62,888 KB
実行使用メモリ 100,876 KB
最終ジャッジ日時 2024-06-23 05:26:59
合計ジャッジ時間 5,131 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 10 ms
29,056 KB
testcase_01 AC 11 ms
23,936 KB
testcase_02 AC 11 ms
23,680 KB
testcase_03 AC 10 ms
23,552 KB
testcase_04 WA -
testcase_05 AC 10 ms
23,552 KB
testcase_06 AC 10 ms
23,680 KB
testcase_07 AC 10 ms
23,552 KB
testcase_08 TLE -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
testcase_31 -- -
testcase_32 -- -
testcase_33 -- -
権限があれば一括ダウンロードができます
コンパイルメッセージ
; compiling file "/home/judge/data/code/Main.lisp" (written 23 JUN 2024 05:26:52 AM):

; file: /home/judge/data/code/Main.lisp
; in:
;      DECLAIM (FTYPE (FUNCTION ((ARRAY * 2) * &OPTIONAL FIXNUM) (ARRAY * 2)) MAT-POW)
;     (DECLAIM
;      (FTYPE (FUNCTION ((ARRAY * 2) * &OPTIONAL FIXNUM) (ARRAY * 2)) MAT-POW))
; ==>
;   (SB-C::%PROCLAIM
;    '(FTYPE (FUNCTION ((ARRAY * 2) * &OPTIONAL FIXNUM) (ARRAY * 2)) MAT-POW)
;    (SB-C:SOURCE-LOCATION))
; 
; caught WARNING:
;   * is not permitted as an argument to the FUNCTION type specifier
; 
; caught WARNING:
;   * is not permitted as an argument to the FUNCTION type specifier
; 
; caught WARNING:
;   * is not permitted as an argument to the FUNCTION type specifier
; 
; compilation unit finished
;   caught 3 WARNING conditions


; wrote /home/judge/data/code/Main.fasl
; compilation finished in 0:00:00.104

ソースコード

diff #

(in-package #:cl-user)

;;------------------------------Preferences------------------------------

(eval-when (:compile-toplevel :load-toplevel :execute)
  #+swank (declaim (optimize (speed 3) (safety 2)))
  #-swank (declaim (optimize (speed 3) (safety 0) (debug 0)))
  #+swank (load "~/ghq/github.com/motoshira/atcoder-submission/ac-tools/act.lisp")
  #+swank (ql:quickload :prove)
  #-swank (declaim (sb-ext:muffle-conditions sb-ext:compiler-note))
  #-swank (sb-ext:disable-debugger)
  (pushnew :inline-generic-funcion *features*))

;;;
;;; Beginning of inserted contents
;;;

;; modint functions

(defpackage #:modint
  (:use #:cl)
  (:nicknames #:m #:mod)
  (:shadow #:+
           #:-
           #:*
           #:/)
  (:export #:*mod*
           #:modint
           #:+
           #:-
           #:*
           #:/
           #:mod-inv
           #:mod-power
           #:make-mod-fact-table
           #:mod-combi-with-table
           #:incmodf
           #:decmodf
           #:mulmodf
           #:divmodf))

(in-package #:modint)

(declaim (fixnum *mod*))
(defvar *mod* 1000000007)

(declaim (inline modint)
         (ftype (function (integer) fixnum) modint))
(defun modint (integer)
  ;; (integer) -> (fixnum)
  ;; TODO TLE on big negative integer
  (declare (integer integer))
  (loop while (minusp integer)
        do (incf integer *mod*))
  (the fixnum
       (if (< integer *mod*)
           integer
           (mod integer *mod*))))

(defun %operate (fn args)
  (declare ((function (fixnum fixnum) fixnum) fn))
  (if (null args)
      0
      (reduce (lambda (x y)
                (modint (funcall fn x (modint y))))
              (rest args)
              :initial-value (first args))))

(defun + (&rest args)
  (%operate (lambda (x y)
              (cl:+ x y))
            args))

(defun - (&rest args)
  (%operate (lambda (x y)
              (cl:- x y))
            args))

(defun * (&rest args)
  (%operate (lambda (x y)
              (cl:* x y))
            args))

(defun / (&rest args)
  (%operate (lambda (x y)
              (cl:* x (mod-inv y)))
            args))

;; TODO compiler-macro

(defmacro %expand (fn x y)
  `(modint (funcall (the (function (fixnum fixnum) fixnum)
                         ,fn)
                    ,x
                    (modint ,y))))

(define-compiler-macro m:+ (&whole form &rest args)
  (if (> (length args) 10)
      form
      (reduce (lambda (acc x)
                `(%expand (lambda (x y)
                            (declare (fixnum x y))
                            (cl:+ x y))
                          ,acc
                          ,x))
              (rest args)
              :initial-value `(modint ,(first args)))))

(define-compiler-macro m:- (&whole form &rest args)
  (if (> (length args) 10)
      form
      (reduce (lambda (acc x)
                `(%expand (lambda (x y)
                            (declare (fixnum x y))
                            (cl:- x y))
                          ,acc
                          ,x))
              (rest args)
              :initial-value `(modint ,(first args)))))

(define-compiler-macro m:* (&whole form &rest args)
  (if (> (length args) 10)
      form
      (reduce (lambda (acc x)
                `(%expand (lambda (x y)
                            (declare (fixnum x y))
                            (cl:* x y))
                          ,acc
                          ,x))
              (rest args)
              :initial-value `(modint ,(first args)))))

(define-compiler-macro m:/ (&whole form &rest args)
  (if (> (length args) 10)
      form
      (reduce (lambda (acc x)
                `(%expand (lambda (x y)
                            (declare (fixnum x y))
                            (cl:* x (mod-inv y)))
                          ,acc
                          ,x))
              (rest args)
              :initial-value `(modint ,(first args)))))

(declaim (ftype (function (fixnum) fixnum) mod-inv))
(defun mod-inv (a)
  "Reference:https://qiita.com/drken/items/3b4fdf0a78e7a138cd9a"
  (declare (fixnum a))
  (let ((b *mod*)
        (u 1)
        (v 0))
    (declare (fixnum b u v))
    (loop until (zerop b) do
      (let ((w (truncate a b)))
        (decf (the fixnum a) (the fixnum
                                  (cl:* (the fixnum w)
                                        (the fixnum b))))
        (rotatef (the fixnum a)
                 (the fixnum b))
        (decf (the fixnum u)
              (the fixnum
                   (cl:* (the fixnum w)
                         (the fixnum v))))
        (rotatef u v)))
    (modint u)))

(declaim (ftype (function (fixnum (integer 0)) fixnum) mod-power)
         (inline mod-power))
(defun mod-power (base power)
  ;; Reference:https://qiita.com/drken/items/3b4fdf0a78e7a138cd9a
  (declare (fixnum base)
           ((integer 0) power))
  (loop while (plusp power)
        with res of-type fixnum = 1
        do (psetq base (the fixnum (* base base))
                  power (the (integer 0) (ash power -1))
                  res (the fixnum (if (logbitp 0 power)
                                    (* res base)
                                    res)))
        finally (return res)))

(define-modify-macro incmodf (&optional (val 1)) (lambda (place val) (+ place val)))
(define-modify-macro decmodf (&optional (val 1)) (lambda (place val) (- place val)))
(define-modify-macro mulmodf (&optional (val 1)) (lambda (place val) (* place val)))
(define-modify-macro divmodf (&optional (val 1)) (lambda (place val) (/ place val)))

(declaim (ftype (function (fixnum) (simple-array fixnum 1)) make-mod-table)
         (inline make-mod-fact-table))
(defun make-mod-fact-table (size)
  (declare (fixnum size))
  (let ((table (make-array (1+ size)
                           :element-type 'fixnum)))
    (declare ((simple-array fixnum 1) table))
    (setf (aref table 0) 1)
    (loop for i of-type fixnum below size
          do (setf (aref table (1+ i))
                   (* (aref table i)
                      (the fixnum (1+ i)))))
    table))

(declaim (ftype (function (fixnum fixnum (simple-array fixnum 1)) fixnum) mod-combi-with-table)
         (inline mod-combi-with-table))
(defun mod-combi-with-table (n k table)
  (declare (fixnum n k)
           ((simple-array fixnum 1) table))
  (the fixnum
       (if (or (< n k)
               (< n 0)
               (< k 0))
           0
           (/ (aref table n)
              (aref table k)
              (aref table (the fixnum (cl:- n k)))))))


;;;
;;; End of inserted contents
;;;

;;---------------------------------Body---------------------------------

(in-package #:cl-user)

(declaim (ftype (function ((array * 2)) (array * 2)) copy-matrix))
(defun copy-matrix (matrix)
  (let ((new-mat (make-array (array-dimensions matrix)
                             :element-type (array-element-type matrix)
                             :adjustable (adjustable-array-p matrix))))
    (loop for i of-type fixnum below (array-dimension matrix 0)
          do (loop for j of-type fixnum below (array-dimension matrix 1)
                   do (setf (aref new-mat i j)
                            (aref matrix i j))))
    new-mat))

(declaim (ftype (function ((array * 2)) (array * 2)) rotate-matrix))
(defun rotate-matrix (matrix)
  " Return a matrix two-dimensional array rotated 90 degrees."
  (let ((m (array-dimension matrix 0))
        (n (array-dimension matrix 1)))
    (let ((new-mat (make-array (list n m)
                               :element-type (array-element-type matrix)
                               :adjustable (adjustable-array-p matrix))))
      (loop for i of-type fixnum below m
            do (loop for j of-type fixnum below n
                     do (setf (aref new-mat j (- m i 1))
                              (aref matrix i j))))
      new-mat)))

(declaim (ftype (function ((array * 2)) null) rotate-matrix!))
(defun rotate-matrix! (matrix)
  " Destructively rotate MATRIX."
  (destructuring-bind (m n) (array-dimensions matrix)
    (loop for i of-type fixnum below n
          do (loop for j of-type fixnum below m
                   do (rotatef (aref matrix j (- n i 1))
                               (aref matrix i j))))))

(declaim (ftype (function ((array * 2) (array * 2) &optional fixnum) (array * 2)) mat*))
(defun mat* (mat1 mat2 &optional modulo)
  (destructuring-bind (m n) (array-dimensions mat1)
    (destructuring-bind (p q) (array-dimensions mat2)
      (assert (= n p))
      (let ((new-mat (make-array (list m q)
                                 :element-type (array-element-type mat1)
                                 :adjustable (adjustable-array-p mat1))))
        (loop for i of-type fixnum below m
              do (loop for j of-type fixnum below q
                       do (setf (aref new-mat i j)
                                (loop for k of-type fixnum below n
                                      sum (if modulo
                                              (mod (* (aref mat1 i k)
                                                      (aref mat2 k j))
                                                   modulo)
                                              (* (aref mat1 i k)
                                                 (aref mat2 k j)))))))
        new-mat))))

(declaim (ftype (function ((array * 2) * &optional fixnum) (array * 2)) mat-pow))
(defun mat-pow (mat k &optional modulo)
  (destructuring-bind (m n) (array-dimensions mat)
    (assert (= m n))
    (let ((res (make-array (list m n)
                           :element-type (array-element-type mat)
                           :adjustable (adjustable-array-p mat)
                           :initial-element 0)))
      (loop for i of-type fixnum below n
            do (setf (aref res i i) 1))
      (let ((base (make-array (list m n)
                              :element-type (array-element-type mat)
                              :adjustable (adjustable-array-p mat)
                              :initial-element 0)))
        (loop for i of-type fixnum below n
              :do (setf (aref base i i) 1))
        (loop :while (plusp k)
              :do (psetf res (if (oddp k)
                                 (mat* res base modulo)
                                 res)
                         base (mat* base base modulo)
                         k (ash k -1)))
        res))))


(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 obj
      (princ obj stream)
      (terpri stream))))

(defun read-into (count &optional (result-type 'list) (reader #'read))
  (coerce (loop :repeat count :collect (funcall reader)) result-type))

(defun main ()
  (let* ((n (read))
         (m (read))
         (time (read))
         (es (read-into m 'vector (lambda () (list (read) (read)))))
         (am (make-array (list n n) :element-type 'fixnum
                                    :initial-element 0)))
    (loop :for (a b) :across es
          :do (setf (aref am a b) 1)
              (setf (aref am b a) 1))
    (let* ((dub (make-array 65))
           (modulo 998244353))
      (declare (fixnum modulo))
      (setf (aref dub 0) am)
      (dotimes (d 64)
        (setf (aref dub (1+ d))
              (mat* (aref dub d)
                    (aref dub d)
                    modulo)))
      (let ((res (make-array (list n n) :element-type 'fixnum
                                        :initial-element 0))
            (d 0)
            (k time))
        (setf (aref res 0 0) 1)
        (loop :while (plusp k)
              :do (psetf k (ash k -1)
                         res (if (oddp k)
                                 (mat* (aref dub d)
                                       res
                                       modulo)
                                 res)
                         d (1+ d)))
        (println (aref res 0 0))))))

#-swank (main)

#+swank
(defun run ()
  (let ((*standard-input*
          (make-string-input-stream
           (with-output-to-string (*standard-output*)
             (run-program
              (merge-pathnames "copy-or-paste" (truename "~/bin/"))
              '()
              :output *standard-output*)))))
    (main)))
0