;; -*- 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 (inline inverse-divisor-transform!))
(defun inverse-divisor-transform! (vector &optional (op- #'-) (handle-zero t))
  "Does the inverse transform of DIVISOR-TRANSFORM! in O(nloglog(n)). Ignores
VECTOR[0] when HANDLE-ZERO is NIL."
  (declare (vector vector))
  (let* ((n (length vector))
         (sieve (make-array n :element-type 'bit :initial-element 1)))
    (loop for p from 2 below n
          when (= 1 (sbit sieve p))
          do (loop for k from (- (ceiling n p) 1) downto 1
                   for pmult of-type fixnum = (* k p)
                   do (setf (sbit sieve pmult) 0)
                      (setf (aref vector pmult)
                            (funcall op- (aref vector pmult) (aref vector k)))))
    (when handle-zero
      (loop for i from 1 below n
            do (setf (aref vector 0)
                     (funcall op- (aref vector 0) (aref vector i)))))
    vector))

;;;
;;; Arithmetic operations with static modulus
;;;

(defmacro define-mod-operations (divisor)
  `(progn
     (defun mod* (&rest args)
       (reduce (lambda (x y) (mod (* x y) ,divisor)) args))

     (sb-c:define-source-transform mod* (&rest args)
       (if (null args)
           1
           (reduce (lambda (x y) `(mod (* ,x ,y) ,',divisor)) args)))

     (defun mod+ (&rest args)
       (reduce (lambda (x y) (mod (+ x y) ,divisor)) args))

     (sb-c:define-source-transform mod+ (&rest args)
       (if (null args)
           0
           (reduce (lambda (x y) `(mod (+ ,x ,y) ,',divisor)) args)))

     (defun mod- (&rest args)
       (reduce (lambda (x y) (mod (- x y) ,divisor)) args))

     (sb-c:define-source-transform mod- (&rest args)
       (reduce (lambda (x y) `(mod (- ,x ,y) ,',divisor)) args))

     (define-modify-macro incfmod (delta)
       (lambda (x y) (mod (+ x y) ,divisor)))

     (define-modify-macro decfmod (delta)
       (lambda (x y) (mod (- x y) ,divisor)))

     (define-modify-macro mulfmod (multiplier)
       (lambda (x y) (mod (* x y) ,divisor)))))

(declaim (inline read-schar))
(defun read-schar (&optional (stream *standard-input*))
  (declare #-swank (sb-kernel:ansi-stream stream)
           (inline read-byte))
  #+swank (read-char stream nil #\Newline) ; on SLIME
  #-swank (code-char (read-byte stream nil #.(char-code #\Newline))))

(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+  998244353)

;;;
;;; Body
;;;

(define-mod-operations +mod+)
(declaim (inline bit-vector-to-integer))
(defun bit-vector-to-integer (bit-vector modulus start end)
  (let ((result 0))
    (declare (uint31 result))
    (loop for i from start below end
          do (setq result
                   (mod (+ (* 2 result) (aref bit-vector i)) modulus)))
    result))

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (xs (make-array n :element-type 'bit))
         (dp (make-array (+ 1 (* 2 n)) :element-type 'uint31 :initial-element 0)))
    (declare (uint31 n))
    (dotimes (i n)
      (setf (aref xs i) (if (char= #\0 (read-schar)) 0 1)))
    (loop for d from 2 to (* 2 n)
          for value of-type uint31 = 0
          when (and (zerop (mod (* 2 n) d))
                    (oddp (floor (* 2 n) d)))
          do (let* ((d/2 (floor d 2))
                    (max-prefix-int (bit-vector-to-integer xs +mod+ 0 d/2))
                    (seq (concatenate 'simple-bit-vector
                                      (subseq xs 0 d/2)
                                      (bit-not (subseq xs 0 d/2) t))))
               (Declare (uint31 d/2 max-prefix-int))
               (incfmod value max-prefix-int)
               (let ((max-seq (make-array n :element-type 'bit)))
                 (loop for i below n
                       do (setf (aref max-seq i)
                                (aref seq (mod i d))))
                 (loop for i below n
                       for i%d = 0 then (if (= (+ i%d 1) d) 0 (+ i%d 1))
                       do (cond ((> (aref max-seq i%d) (aref xs i))
                                 (return))
                                ((< (aref max-seq i%d) (aref xs i))
                                 (incfmod value 1)
                                 (return)))
                       finally (incfmod value 1))))
             (setf (aref dp d) value))
    (inverse-divisor-transform! dp #'mod-)
    (loop with res of-type uint31 = 0
          for d from 2 to (* 2 n)
          when (and (zerop (mod (* 2 n) d))
                    (oddp (floor (* 2 n) d)))
          do (incfmod res (mod* d (aref dp d)))
          finally (println res))))

#-swank (main)


Measured memory_bytes: 75112