Problem:
Score : 700 points

Problem Statement

We have an integer sequence of length N: A_0,A_1,\cdots,A_{N-1}.

Find the following sum (\mathrm{lcm}(a, b) denotes the least common multiple of a and b):

\sum_{i=0}^{N-2} \sum_{j=i+1}^{N-1} \mathrm{lcm}(A_i,A_j)

Since the answer may be enormous, compute it modulo 998244353.

Constraints

1 \leq N \leq 200000

1 \leq A_i \leq 1000000

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_0\ A_1\ \cdots\ A_{N-1}

Output

Print the sum modulo 998244353.

Sample Input 1

3
2 4 6

Sample Output 1

22

\mathrm{lcm}(2,4)+\mathrm{lcm}(2,6)+\mathrm{lcm}(4,6)=4+6+12=22.

Sample Input 2

8
1 2 3 4 6 8 12 12

Sample Output 2

313

Sample Input 3

10
356822 296174 484500 710640 518322 888250 259161 609120 592348 713644

Sample Output 3

353891724

Solution in Common Lisp (SBCL 1.1.14) (judge verdict: Accepted)

;; -*- 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
(defconstant +mod+ 998244353)

;; BEGIN_INSERTED_CONTENTS
;;;
;;; Binomial coefficient with mod
;;; build: O(n)
;;; query: O(1)
;;;

;; TODO: non-global handling

(defconstant +binom-size+ 1100000)
(defconstant +binom-mod+ +mod+)

(declaim ((simple-array (unsigned-byte 32) (*)) *inv*))
(defparameter *inv* (make-array +binom-size+ :element-type '(unsigned-byte 32))
  "table of inverses of non-negative integers")

(defun initialize-binom ()
  (declare (optimize (speed 3) (safety 0)))
  (setf (aref *inv* 1) 1)
  (loop for i from 2 below +binom-size+
        do (setf (aref *inv* i) (- +binom-mod+
                                   (mod (* (aref *inv* (rem +binom-mod+ i))
                                           (floor +binom-mod+ i))
                                        +binom-mod+)))))

(initialize-binom)

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

;;;
;;; 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)
       (if (null args)
           0
           (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 multiple-transform!))
(defun multiple-transform! (vector &optional (op+ #'+) (handle-zero t))
  "Sets each VECTOR[i] to the sum of VECTOR[m] for all the multiples m of i in
O(nloglog(n)). (To be precise, all the multiples smaller than the length of
VECTOR.) 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 k)
                            (funcall op+ (aref vector k) (aref vector pmult)))))
    (when handle-zero
      (loop for i from 1 below n
            do (setf (aref vector i)
                     (funcall op+ (aref vector 0) (aref vector i)))))
    vector))

(declaim (inline inverse-multiple-transform!))
(defun inverse-multiple-transform! (vector &optional (op- #'-) (handle-zero t))
  "Does the inverse transform of MULTIPLE-TRANSFORM!. 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)))
    (when handle-zero
      (loop for i from 1 below n
            do (setf (aref vector i)
                     (funcall op- (aref vector i) (aref vector 0)))))
    (loop for p from 2 below n
          when (= 1 (sbit sieve p))
          do (loop for k from 1 below (ceiling n p)
                   for pmult of-type fixnum = (* k p)
                   do (setf (sbit sieve pmult) 0)
                      (setf (aref vector k)
                            (funcall op- (aref vector k) (aref vector pmult)))))
    vector))

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

;;;
;;; Body
;;;

(define-mod-operations +mod+)

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (as (make-array n :element-type 'uint31))
         (dp (make-array 1000001 :element-type 'uint31 :initial-element 0)))
    (declare (uint31 n))
    (dotimes (i n)
      (let ((a (read-fixnum)))
        (incfmod (aref dp a) a)
        (setf (aref as i) a)))
    (multiple-transform! dp #'mod+ nil)
    (dotimes (i (length dp))
      (setf (aref dp i) (mod* (aref dp i) (aref dp i))))
    (inverse-multiple-transform! dp
                                 (lambda (x y)
                                   (declare (uint31 x y))
                                   (let ((res (+ x (- +mod+ y))))
                                     (if (>= res +mod+)
                                         (- res +mod+)
                                         res)))
                                 nil)
    (loop for a across as
          do (incfmod (aref dp a) (- +mod+ (mod* a a))))
    (loop for i from 1 below (length dp)
          do (setf (aref dp i)
                   (mod* (aref dp i) (aref *inv* i))))
    (println (mod* (mod (loop for x across dp sum x of-type uint62) +mod+)
                   (aref *inv* 2)))))

#-swank (main)