結果
問題 | No.885 アマリクエリ |
ユーザー |
|
提出日時 | 2019-09-13 22:52:44 |
言語 | Common Lisp (sbcl 2.5.0) |
結果 |
AC
|
実行時間 | 502 ms / 2,000 ms |
コード長 | 6,650 bytes |
コンパイル時間 | 478 ms |
コンパイル使用メモリ | 84,992 KB |
実行使用メモリ | 30,720 KB |
最終ジャッジ日時 | 2024-07-04 10:12:24 |
合計ジャッジ時間 | 4,428 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 19 |
コンパイルメッセージ
; compiling file "/home/judge/data/code/Main.lisp" (written 04 JUL 2024 10:12:18 AM): ; wrote /home/judge/data/code/Main.fasl ; compilation finished in 0:00:00.279
ソースコード
;; -*- coding: utf-8 -*-(eval-when (:compile-toplevel :load-toplevel :execute)(sb-int:defconstant-eqx OPT#+swank '(optimize (speed 3) (safety 2))#-swank '(optimize (speed 3) (safety 0) (debug 0))#'equal)#+swank (ql:quickload '(:cl-debug-print :fiveam) :silent t)#-swank (set-dispatch-macro-character#\# #\> (lambda (s c p) (declare (ignore c p)) (read s nil nil t))))#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)#-swank (disable-debugger) ; for CS Academy;; BEGIN_INSERTED_CONTENTS(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))))))));;;;;; Disjoint sparse table on arbitrary semigroup;;;;;; Reference:;;; https://discuss.codechef.com/questions/117696/tutorial-disjoint-sparse-table;;; http://noshi91.hatenablog.com/entry/2018/05/08/183946 (Japanese);;; http://drken1215.hatenablog.com/entry/2018/09/08/162600 (Japanese);; NOTE: This constructor is slow on SBCL version earlier than 1.5.6 as the type;; propagation of MAKE-ARRAY doesn't work. The following files are required to;; enable the optimization.;; version < 1.5.0: array-element-type.lisp, make-array-header.lisp;; version < 1.5.6: make-array-header.lisp(declaim (inline make-disjoint-sparse-table))(defun make-disjoint-sparse-table (vector binop)"BINOP := binary operator (comprising a semigroup)"(let* ((n (length vector))(height (integer-length (- n 1)))(table (make-array (list height n) :element-type '(unsigned-byte 32))))(dotimes (j n)(setf (aref table 0 j) (aref vector j)))(do ((i 1 (+ i 1)))((>= i height))(let* ((width/2 (ash 1 i))(width (* width/2 2)))(do ((j 0 (+ j width)))((>= j n))(let ((mid (min (+ j width/2) n)));; fill the first half(setf (aref table i (- mid 1))(aref vector (- mid 1)))(do ((k (- mid 2) (- k 1)))((< k j))(setf (aref table i k)(funcall binop (aref vector k) (aref table i (+ k 1)))))(when (>= mid n)(return));; fill the second half(setf (aref table i mid)(aref vector mid))(let ((end (min n (+ mid width/2))))(do ((k (+ mid 1) (+ k 1)))((>= k end))(setf (aref table i k)(funcall binop (aref table i (- k 1)) (aref vector k)))))))))table))(declaim (inline dst-query))(defun dst-query (table binop left right &optional identity)"Queries the interval [LEFT, RIGHT). Returns IDENTITY for a null interval [x,x)."(declare ((integer 0 #.most-positive-fixnum) left right)((simple-array * (* *)) table))(when (>= left right)(assert (= left right))(return-from dst-query identity))(setq right (- right 1)) ;; change to closed interval(if (= left right)(aref table 0 left)(let ((h (- (integer-length (logxor left right)) 1)))(funcall binop(aref table h left)(aref table h right)))))(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 ()(let* ((n (read))(as (make-array n :element-type 'uint32)))(dotimes (i n) (setf (aref as i) (read-fixnum)))(let* ((q (read))(xs (make-array q :element-type 'uint32))(deltas (make-array q :element-type 'fixnum :initial-element 0)))(dotimes (i q) (setf (aref xs i) (read-fixnum)))(let ((dtable (make-disjoint-sparse-table xs #'min)))(declare ((simple-array uint32 (* *)) dtable))(dotimes (i n)(let ((value (aref as i))(prev-pos 0))(declare (fixnum value prev-pos));; (terpri)(loop(unless (<= (dst-query dtable #'min prev-pos q #xffffffff) value)(return))(let* ((new-pos (sb-int:named-let bisect ((ng prev-pos) (ok q))(declare (int32 ng ok))(if (<= (- ok ng) 1)(- ok 1)(let* ((mid (ash (+ ng ok) -1))(min (dst-query dtable #'min prev-pos mid #xffffffff)))(if (<= min value)(bisect ng mid)(bisect mid ok))))))(new-value (mod value (aref xs new-pos))))(decf (aref deltas new-pos) (- value new-value))(setq prev-pos new-posvalue new-value))))))(let ((sum (reduce #'+ as)))(dotimes (i q)(incf sum (aref deltas i))(println sum))))))#-swank (main)