提出 #6107568


ソースコード 拡げる

;; -*- 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 (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :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)

;; BEGIN_INSERTED_CONTENTS
(defmacro with-output-buffer (&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*))
  (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))))))))

;;;
;;; Rolling hash
;;;

;; TODO: handle multiple moduli together
(defstruct (rhash (:constructor %make-rhash (divisor cumul powers)))
  (divisor 1000000007 :type (unsigned-byte 32))
  (cumul nil :type (simple-array (unsigned-byte 32) (*)))
  (powers nil :type (simple-array (unsigned-byte 32) (*))))

(defun make-rhash (vector divisor &key (key #'char-code) base)
  "Returns the table of rolling-hash of VECTOR modulo DIVISOR. KEY is applied to
  each element of VECTOR prior to computing the hash value.

DIVISOR := unsigned 32-bit prime number
BASE := 1 | 2 | ... | DIVISOR - 1
KEY := function returning FIXNUM"
  (declare #.OPT
           (vector vector)
           ((unsigned-byte 32) divisor)
           ((or null (unsigned-byte 32)) base)
           (function key))
  (assert (sb-int:positive-primep divisor))
  (let* ((base (or base (+ 1 (random (- divisor 1)))))
         (size (length vector))
         (cumul (make-array (+ 1 size) :element-type '(unsigned-byte 32)))
         (powers (make-array (+ 1 size) :element-type '(unsigned-byte 32))))
    (assert (<= 1 base (- divisor 1)))
    (setf (aref powers 0) 1)
    (dotimes (i size)
      (setf (aref powers (+ i 1))
            (mod (* (aref powers i) base) divisor))
      (let ((sum (+ (mod (* (aref cumul i) base) divisor)
                    (mod (the fixnum (funcall key (aref vector i))) divisor))))
        (setf (aref cumul (+ i 1))
              (if (> sum divisor)
                  (- sum divisor)
                  sum))))
    (%make-rhash divisor cumul powers)))

(declaim (inline rhash-query)
         (ftype (function * (values (unsigned-byte 32) &optional)) rhash-query))
(defun rhash-query (rhash l r)
  "Returns the hash value of the interval [L, R)."
  (declare ((integer 0 #.most-positive-fixnum) l r))
  (assert (<= l r))
  (let ((cumul (rhash-cumul rhash))
        (powers (rhash-powers rhash))
        (divisor (rhash-divisor rhash)))
    (let ((res (+ (aref cumul r)
                  (- divisor (mod (* (aref cumul l) (aref powers (- r l))) divisor)))))
      (if (> res divisor)
          (- res divisor)
          res))))

(declaim (inline rhash-concat))
(defun rhash-concat (rhash hash1 hash2 hash2-length)
  (declare ((unsigned-byte 32) hash1 hash2)
           ((integer 0 #.most-positive-fixnum) hash2-length))
  (let* ((divisor (rhash-divisor rhash)))
    (mod (+ hash2
            (mod (* hash1
                    (aref (rhash-powers rhash) hash2-length))
                 divisor))
         divisor)))

(declaim (inline rhash-get-lcp))
(defun rhash-get-lcp (rhash1 start1 rhash2 start2)
  (declare ((integer 0 #.most-positive-fixnum) start1 start2))
  (assert (= (rhash-divisor rhash1) (rhash-divisor rhash2)))
  (assert (and (< start1 (length (rhash-cumul rhash1)))
               (< start2 (length (rhash-cumul rhash2)))))
  (let ((max-length (min (- (length (rhash-cumul rhash1)) start1 1)
                         (- (length (rhash-cumul rhash2)) start2 1))))
    (if (= (rhash-query rhash1 start1 (+ start1 max-length))
           (rhash-query rhash2 start2 (+ start2 max-length)))
        max-length
        (labels ((bisect (ok ng)
                   (declare ((integer 0 #.most-positive-fixnum) ok ng))
                   (if (<= (- ng ok) 1)
                       ok
                       (let ((mid (ash (+ ng ok) -1)))
                         (if (= (rhash-query rhash1 start1 (+ start1 mid))
                                (rhash-query rhash2 start2 (+ start2 mid)))
                             (bisect mid ng)
                             (bisect ok mid))))))
          (bisect 0 max-length)))))

(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 (ftype (function * (values uint32 &optional)) concat))
(defun concat (rhash l r pos char)
  (declare #.OPT (uint32 l r pos))
  (assert (<= l r))
  (if (and (<= l pos) (< pos r))
      (rhash-concat rhash
                    (rhash-concat rhash (rhash-query rhash l pos) (char-code char) 1)
                    (rhash-query rhash (+ pos 1) r)
                    (- r pos 1))
      (rhash-query rhash l r)))

(defun main ()
  (declare #.OPT)
  (let* ((s (coerce (read-line) 'simple-base-string))
         (q (read))
         (rhash1 (make-rhash s 1000000007))
         (rhash2 (make-rhash s 1000000009)))
    (declare (uint32 q)
             (simple-base-string s))
    (with-output-buffer
      (dotimes (i q)
        (let* ((l (- (read-fixnum) 1))
               (r (read-fixnum))
               (period (read-fixnum))
               (lcp (min (rhash-get-lcp rhash1 l rhash1 (+ l period))
                         (rhash-get-lcp rhash2 l rhash2 (+ l period)))))
          (declare (uint32 l r period lcp))
          ;; #>lcp
          (if (or (>= lcp (- r l period))
                  (and (= (concat rhash1 l (- r period) (+ l lcp) (aref s (+ l period lcp)))
                          (concat rhash1 (+ l period) r (+ l lcp) (aref s (+ l period lcp))))
                       (= (concat rhash2 l (- r period) (+ l lcp) (aref s (+ l period lcp)))
                          (concat rhash2 (+ l period) r (+ l lcp) (aref s (+ l period lcp)))))
                  (and (= (concat rhash1 l (- r period) (+ l period lcp) (aref s (+ l lcp)))
                          (concat rhash1 (+ l period) r (+ l period lcp) (aref s (+ l lcp))))
                       (= (concat rhash2 l (- r period) (+ l period lcp) (aref s (+ l lcp)))
                          (concat rhash2 (+ l period) r (+ l period lcp) (aref s (+ l lcp))))))
              (write-line "Yes")
              (write-line "No")))))))

#-swank(main)

提出情報

提出日時
問題 F - ほぼ周期文字列
ユーザ sansaqua
言語 Common Lisp (SBCL 1.1.14)
得点 100
コード長 8544 Byte
結果 AC
実行時間 389 ms
メモリ 46184 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 100 / 100
結果
AC × 2
AC × 39
セット名 テストケース
Sample sample_01.txt, sample_02.txt
All sample_01.txt, sample_02.txt, subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask1_13.txt, subtask1_14.txt, subtask1_15.txt, subtask1_16.txt, subtask1_17.txt, subtask1_18.txt, subtask1_19.txt, subtask1_20.txt, subtask1_21.txt, subtask1_22.txt, subtask1_23.txt, subtask1_24.txt, subtask1_25.txt, subtask1_26.txt, subtask1_27.txt, subtask1_28.txt, subtask1_29.txt, subtask1_30.txt, subtask1_31.txt, subtask1_32.txt, subtask1_33.txt, subtask1_34.txt, subtask1_35.txt, subtask1_36.txt, subtask1_37.txt
ケース名 結果 実行時間 メモリ
sample_01.txt AC 335 ms 46184 KiB
sample_02.txt AC 160 ms 33380 KiB
subtask1_01.txt AC 334 ms 37732 KiB
subtask1_02.txt AC 335 ms 37732 KiB
subtask1_03.txt AC 325 ms 37736 KiB
subtask1_04.txt AC 312 ms 37732 KiB
subtask1_05.txt AC 362 ms 37732 KiB
subtask1_06.txt AC 309 ms 37732 KiB
subtask1_07.txt AC 335 ms 37736 KiB
subtask1_08.txt AC 334 ms 37732 KiB
subtask1_09.txt AC 330 ms 37864 KiB
subtask1_10.txt AC 320 ms 37732 KiB
subtask1_11.txt AC 276 ms 37864 KiB
subtask1_12.txt AC 357 ms 37732 KiB
subtask1_13.txt AC 360 ms 37732 KiB
subtask1_14.txt AC 358 ms 37732 KiB
subtask1_15.txt AC 358 ms 37736 KiB
subtask1_16.txt AC 380 ms 37736 KiB
subtask1_17.txt AC 367 ms 37732 KiB
subtask1_18.txt AC 370 ms 37732 KiB
subtask1_19.txt AC 374 ms 37732 KiB
subtask1_20.txt AC 378 ms 37732 KiB
subtask1_21.txt AC 378 ms 37728 KiB
subtask1_22.txt AC 376 ms 37736 KiB
subtask1_23.txt AC 376 ms 37732 KiB
subtask1_24.txt AC 378 ms 37732 KiB
subtask1_25.txt AC 387 ms 37732 KiB
subtask1_26.txt AC 382 ms 37732 KiB
subtask1_27.txt AC 376 ms 37732 KiB
subtask1_28.txt AC 368 ms 37736 KiB
subtask1_29.txt AC 370 ms 37728 KiB
subtask1_30.txt AC 372 ms 37732 KiB
subtask1_31.txt AC 383 ms 37736 KiB
subtask1_32.txt AC 377 ms 37732 KiB
subtask1_33.txt AC 386 ms 37732 KiB
subtask1_34.txt AC 375 ms 37728 KiB
subtask1_35.txt AC 385 ms 37728 KiB
subtask1_36.txt AC 389 ms 37732 KiB
subtask1_37.txt AC 386 ms 37732 KiB