Submission #6722764
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 (ql:quickload '(:cl-debug-print :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)
#-swank (disable-debugger) ; for CS Academy
;; BEGIN_INSERTED_CONTENTS
;; Treap accessible by index (O(log(n))).
;; Virtually it works like std::set of C++ or TreeSet of Java.
;; Note:
;; - You shouldn't insert duplicate keys into a treap unless you know what you
;; are doing.
;; - You cannot rely on the side effect when you call any destructive operations
;; on a treap. Always use the returned value.
;; - An empty treap is NIL.
(defstruct (treap (:constructor %make-treap (key priority &key left right (count 1)))
(:copier nil)
(:conc-name %treap-))
(key 0 :type fixnum)
(priority 0 :type (integer 0 #.most-positive-fixnum))
(count 0 :type (integer 0 #.most-positive-fixnum))
(left nil :type (or null treap))
(right nil :type (or null treap)))
(declaim (inline treap-count))
(defun treap-count (treap)
"Returns the size of the (nullable) TREAP."
(declare ((or null treap) treap))
(if (null treap)
0
(%treap-count treap)))
(declaim (inline update-count))
(defun update-count (treap)
(declare (treap treap))
(setf (%treap-count treap)
(+ 1
(treap-count (%treap-left treap))
(treap-count (%treap-right treap)))))
(declaim (inline treap-bisect-left)
(ftype (function * (values (integer 0 #.most-positive-fixnum) t &optional)) treap-bisect-left))
(defun treap-bisect-left (value treap &key (order #'<))
"Returns the smallest index and the corresponding key that satisfies
TREAP[index] >= VALUE. Returns the size of TREAP and VALUE if TREAP[size-1] <
VALUE."
(declare (function order))
(labels ((recur (count treap)
(declare ((integer 0 #.most-positive-fixnum) count))
(cond ((null treap) (values nil nil))
((funcall order (%treap-key treap) value)
(recur count (%treap-right treap)))
(t (let ((left-count (- count (treap-count (%treap-right treap)) 1)))
(multiple-value-bind (idx key)
(recur left-count (%treap-left treap))
(if idx
(values idx key)
(values left-count (%treap-key treap)))))))))
(declare (ftype (function * (values t t &optional)) recur))
(multiple-value-bind (idx key)
(recur (treap-count treap) treap)
(if idx
(values idx key)
(values (treap-count treap) value)))))
(declaim (inline treap-split)
(ftype (function * (values (or null treap) (or null treap) &optional)) treap-split))
(defun treap-split (key treap &key (order #'<))
"Destructively splits the TREAP with reference to KEY and returns two treaps,
the smaller sub-treap (< KEY) and the larger one (>= KEY)."
(declare (function order)
((or null treap) treap))
(labels ((recur (treap)
(cond ((null treap)
(values nil nil))
((funcall order (%treap-key treap) key)
(multiple-value-bind (left right) (recur (%treap-right treap))
(setf (%treap-right treap) left)
(update-count treap)
(values treap right)))
(t
(multiple-value-bind (left right) (recur (%treap-left treap))
(setf (%treap-left treap) right)
(update-count treap)
(values left treap))))))
(recur treap)))
(declaim (inline treap-insert))
(defun treap-insert (key treap &key (order #'<))
"Destructively inserts KEY into TREAP and returns the resultant treap."
(declare ((or null treap) treap)
(function order))
(let ((node (%make-treap key (random most-positive-fixnum))))
(labels ((recur (treap)
(declare (treap node))
(cond ((null treap) node)
((> (%treap-priority node) (%treap-priority treap))
(setf (values (%treap-left node) (%treap-right node))
(treap-split (%treap-key node) treap :order order))
(update-count node)
node)
(t
(if (funcall order (%treap-key node) (%treap-key treap))
(setf (%treap-left treap)
(recur (%treap-left treap)))
(setf (%treap-right treap)
(recur (%treap-right treap))))
(update-count treap)
treap))))
(recur treap))))
(defun treap-map (function treap)
"Successively applies FUNCTION to TREAP[0], ..., TREAP[SIZE-1]. FUNCTION must
take one argument."
(declare (function function))
(when treap
(treap-map function (%treap-left treap))
(funcall function (%treap-key treap))
(treap-map function (%treap-right treap))))
(defmethod print-object ((object treap) stream)
(print-unreadable-object (object stream :type t)
(let ((init t))
(treap-map (lambda (key)
(if init
(setq init nil)
(write-char #\ stream))
(write key :stream stream))
object))))
(define-condition invalid-treap-index-error (type-error)
((treap :initarg :treap :reader invalid-treap-index-error-treap)
(index :initarg :index :reader invalid-treap-index-error-index))
(:report
(lambda (condition stream)
(format stream "Invalid index ~W for treap ~W."
(invalid-treap-index-error-index condition)
(invalid-treap-index-error-treap condition)))))
(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))))))))
(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
;;;
;;; Arithmetic operations with static modulus
;;;
(defmacro define-mod-operations (&optional (divisor 1000000007))
`(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)))
(define-modify-macro incfmod (delta divisor)
(lambda (x y divisor) (mod (+ x y) divisor)))
(define-modify-macro decfmod (delta divisor)
(lambda (x y divisor) (mod (- x y) divisor)))))
(define-mod-operations 998244353)
(defun main ()
(declare #.OPT
(inline sort))
(let* ((n (read))
(xs (make-array n :element-type 'int32))
(ys (make-array n :element-type 'int32))
(powers (make-array 200001 :element-type 'uint32))
(ord-xs (make-array n :element-type 'uint32))
(res 0))
(declare (uint32 n res)
((simple-array uint32 (*)) ord-xs))
;; construct table of 2^n
(setf (aref powers 0) 1)
(loop for i from 1 below (length powers)
do (setf (aref powers i)
(mod* 2 (aref powers (- i 1)))))
(dotimes (i n)
(setf (aref xs i) (read-fixnum)
(aref ys i) (read-fixnum)))
(dotimes (i n)
(setf (aref ord-xs i) i))
(setf ord-xs (sort ord-xs (lambda (i j) (< (aref xs i) (aref xs j)))))
;; L R U D
(incfmod res (mod* (- n 4) (- (aref powers n) 1)) +mod+)
;; LU LD
(let (treap)
(loop for i from 0 below n
do (let* ((ord (aref ord-xs i))
(y (aref ys ord))
(ld (treap-bisect-left y treap))
(lu (- (treap-count treap) ld)))
(incfmod res (aref powers ld) +mod+)
(incfmod res (aref powers lu) +mod+)
(setq treap (treap-insert y treap)))))
;; RU RD
(let (treap)
(loop for i from (- n 1) downto 0
do (let* ((ord (aref ord-xs i))
(y (aref ys ord))
(rd (treap-bisect-left y treap))
(ru (- (treap-count treap) rd)))
(incfmod res (aref powers rd) +mod+)
(incfmod res (aref powers ru) +mod+)
(setq treap (treap-insert y treap)))))
(println res)))
#-swank (main)
Submission Info
Submission Time |
|
Task |
F - Enclosed Points |
User |
sansaqua |
Language |
Common Lisp (SBCL 1.1.14) |
Score |
600 |
Code Size |
10875 Byte |
Status |
AC |
Exec Time |
700 ms |
Memory |
66660 KiB |
Judge Result
Set Name |
Sample |
All |
Score / Max Score |
0 / 0 |
600 / 600 |
Status |
|
|
Set Name |
Test Cases |
Sample |
s1.txt, s2.txt, s3.txt |
All |
01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, s1.txt, s2.txt, s3.txt |
Case Name |
Status |
Exec Time |
Memory |
01.txt |
AC |
295 ms |
57828 KiB |
02.txt |
AC |
269 ms |
56292 KiB |
03.txt |
AC |
269 ms |
56288 KiB |
04.txt |
AC |
274 ms |
56288 KiB |
05.txt |
AC |
269 ms |
56292 KiB |
06.txt |
AC |
270 ms |
56292 KiB |
07.txt |
AC |
269 ms |
56288 KiB |
08.txt |
AC |
271 ms |
56292 KiB |
09.txt |
AC |
269 ms |
56292 KiB |
10.txt |
AC |
269 ms |
56288 KiB |
11.txt |
AC |
691 ms |
66660 KiB |
12.txt |
AC |
679 ms |
66532 KiB |
13.txt |
AC |
700 ms |
66532 KiB |
14.txt |
AC |
675 ms |
66536 KiB |
15.txt |
AC |
697 ms |
66536 KiB |
16.txt |
AC |
692 ms |
66536 KiB |
17.txt |
AC |
691 ms |
66532 KiB |
18.txt |
AC |
697 ms |
66532 KiB |
19.txt |
AC |
510 ms |
66536 KiB |
20.txt |
AC |
507 ms |
66532 KiB |
21.txt |
AC |
553 ms |
66536 KiB |
22.txt |
AC |
555 ms |
66528 KiB |
23.txt |
AC |
269 ms |
56296 KiB |
s1.txt |
AC |
269 ms |
56288 KiB |
s2.txt |
AC |
269 ms |
56288 KiB |
s3.txt |
AC |
270 ms |
56288 KiB |