Submission #5787152


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 (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS
;;;
;;; Unfinished. Use fft-recursive.lisp instead.
;;;

(deftype fft-float () 'double-float)

(declaim (inline power2-p))
(defun power2-p (x)
  "Checks if X is a power of 2."
  (zerop (logand x (- x 1))))

(declaim (inline general-dft!))
(defun general-dft! (f sign)
  (declare ((array (complex fft-float) (*)) f)
           ((integer -1 1) sign))
  (prog1 f
    (let* ((n (length f))
           (theta (* sign (/ (coerce (* 2 pi) 'fft-float) n))))
      (declare (fft-float theta))
      (assert (power2-p n))
      (do ((m n (ash m -1)))
          ((= m 1))
        (declare ((integer 0 #.most-positive-fixnum) m))
        (let ((mh (ash m -1)))
          (declare ((integer 0 #.most-positive-fixnum) mh))
          (dotimes (i mh)
            (let ((w (cis (* i theta))))
              (do ((j i (+ j m)))
                  ((>= j n))
                (declare ((integer 0 #.most-positive-fixnum) j))
                (let* ((k (+ j mh))
                       (xt (- (aref f j) (aref f k))))
                  (declare ((integer 0 #.most-positive-fixnum) k))
                  (incf (aref f j) (aref f k))
                  (setf (aref f k) (* w xt))))))
          (setq theta (* theta 2))))
      (let ((i 0))
        (declare ((integer 0 #.most-positive-fixnum) i))
        (loop for j from 1 below (- n 1)
              do (loop for k of-type (integer 0 #.most-positive-fixnum)
                          = (ash n -1) then (ash k -1)
                       while (> k (setq i (logxor i k))))
                 (when (< j i)
                   (rotatef (aref f i) (aref f j))))))))

(declaim (inline dft!))
(defun dft! (f)
  (if (zerop (length f))
      f
      (general-dft! f 1)))

(declaim (inline inverse-dft!))
(defun inverse-dft! (f)
  (declare ((array (complex fft-float) (*)) f))
  (if (zerop (length f))
      f
      (let* ((n (length f))
             (/n (/ (coerce n 'fft-float))))
        (general-dft! f -1)
        (dotimes (i n f)
          (setf (aref f i) (* (aref f i) /n))))))

(declaim (inline convolute!))
(defun convolute! (g h)
  (declare ((array (complex fft-float) (*)) g h))
  (assert (and (power2-p (length g))
               (power2-p (length h))
               (= (length g) (length h))))
  (let ((n (length g)))
    (dft! g)
    (dft! h)
    (let ((f (make-array n :element-type '(complex fft-float))))
      (dotimes (i n)
        (setf (aref f i) (* (aref g i) (aref h i))))
      (inverse-dft! f))))

(defmacro with-output-buffer (&body body)
  "Buffers all outputs to *STANDARD-OUTPUT* and flushes them to
*STANDARD-OUTPUT* at the end. 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
                                  ;; (return-from read-fixnum 0)
                                  (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) (the fixnum (* result 10))))
              (return (if minus (- result) 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)

(defmacro 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)
  (let* ((n (read))
         (length (sb-int:power-of-two-ceiling (+ n n 1)))
         (as (make-array length :element-type '(complex double-float) :initial-element #c(0d0 0d0)))
         (bs (make-array length :element-type '(complex double-float) :initial-element #c(0d0 0d0))))
    (declare (uint32 n))
    (loop for i from 1 to n
          do (setf (aref as i) (coerce (read-fixnum) '(complex double-float))
                   (aref bs i) (coerce (read-fixnum) '(complex double-float))))
    (let ((res (convolute! as bs)))
      (declare ((simple-array (complex double-float) (*)) res))
      (with-output-buffer
        (loop for i from 1 to (* 2 n)
              do (println (round (the (double-float -4.6d18 4.6d18)
                                      (realpart (aref res i))))))))))

#-swank(main)

Submission Info

Submission Time
Task C - 高速フーリエ変換
User sansaqua
Language Common Lisp (SBCL 1.1.14)
Score 100
Code Size 6116 Byte
Status AC
Exec Time 684 ms
Memory 67940 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 100 / 100
Status
AC × 1
AC × 33
Set Name Test Cases
Sample 00_sample_01
All 00_sample_01, 01_00_01, 01_01_19, 01_02_31, 01_03_22, 01_04_31, 01_05_40, 01_06_15, 01_07_39, 01_08_28, 01_09_30, 01_10_23, 01_11_33, 01_12_11, 01_13_28, 01_14_41, 01_15_26, 01_16_49, 01_17_34, 01_18_02, 01_19_33, 01_20_29, 02_00_51254, 02_01_82431, 02_02_17056, 02_03_34866, 02_04_6779, 02_05_65534, 02_06_65535, 02_07_65536, 02_08_65537, 02_09_65538, 02_10_100000
Case Name Status Exec Time Memory
00_sample_01 AC 440 ms 66536 KB
01_00_01 AC 283 ms 53860 KB
01_01_19 AC 283 ms 53856 KB
01_02_31 AC 282 ms 53860 KB
01_03_22 AC 284 ms 53860 KB
01_04_31 AC 291 ms 53728 KB
01_05_40 AC 283 ms 53864 KB
01_06_15 AC 282 ms 53856 KB
01_07_39 AC 284 ms 53860 KB
01_08_28 AC 283 ms 53856 KB
01_09_30 AC 282 ms 53860 KB
01_10_23 AC 286 ms 53860 KB
01_11_33 AC 282 ms 53860 KB
01_12_11 AC 282 ms 53864 KB
01_13_28 AC 282 ms 53856 KB
01_14_41 AC 282 ms 53856 KB
01_15_26 AC 281 ms 53856 KB
01_16_49 AC 282 ms 53860 KB
01_17_34 AC 283 ms 53864 KB
01_18_02 AC 282 ms 53864 KB
01_19_33 AC 282 ms 53860 KB
01_20_29 AC 284 ms 53860 KB
02_00_51254 AC 481 ms 63076 KB
02_01_82431 AC 634 ms 67684 KB
02_02_17056 AC 360 ms 62312 KB
02_03_34866 AC 438 ms 62568 KB
02_04_6779 AC 305 ms 55912 KB
02_05_65534 AC 520 ms 63204 KB
02_06_65535 AC 523 ms 63200 KB
02_07_65536 AC 584 ms 67300 KB
02_08_65537 AC 584 ms 67300 KB
02_09_65538 AC 585 ms 67304 KB
02_10_100000 AC 684 ms 67940 KB