Problem:
Score : 600 points

Problem Statement

Given are two sequences a=\{a_0,\ldots,a_{N-1}\} and b=\{b_0,\ldots,b_{N-1}\} of N non-negative integers each.

Snuke will choose an integer k such that 0 \leq k < N and an integer x not less than 0, to make a new sequence of length N, a'=\{a_0',\ldots,a_{N-1}'\}, as follows:

a_i'= a_{i+k \mod N}\ XOR \ x

Find all pairs (k,x) such that a' will be equal to b.

What is \mbox{ XOR }?

The XOR of integers A and B, A \mbox{ XOR } B, is defined as follows:

When A \mbox{ XOR } B is written in base two, the digit in the 2^k's place (k \geq 0) is 1 if either A or B, but not both, has 1 in the 2^k's place, and 0 otherwise.

For example, 3 \mbox{ XOR } 5 = 6. (In base two: 011 \mbox{ XOR } 101 = 110.)

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq a_i,b_i < 2^{30}

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a_0 a_1 ... a_{N-1}
b_0 b_1 ... b_{N-1}

Output

Print all pairs (k, x) such that a' and b will be equal, using one line for each pair, in ascending order of k (ascending order of x for pairs with the same k).

If there are no such pairs, the output should be empty.

Sample Input 1

3
0 2 1
1 2 3

Sample Output 1

1 3

If (k,x)=(1,3),

a_0'=(a_1\ XOR \ 3)=1

a_1'=(a_2\ XOR \ 3)=2

a_2'=(a_0\ XOR \ 3)=3

and we have a' = b.

Sample Input 2

5
0 0 0 0 0
2 2 2 2 2

Sample Output 2

0 2
1 2
2 2
3 2
4 2

Sample Input 3

6
0 1 3 7 6 4
1 5 4 6 2 3

Sample Output 3

2 2
5 5

Sample Input 4

2
1 2
0 0

Sample Output 4

No pairs may satisfy the condition.

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
           ;; enclose the form with VALUES to avoid being captured by LOOP macro
           #\# #\> (lambda (s c p) (declare (ignore c p)) `(values ,(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
(defmacro with-buffered-stdout (&body body)
  "Buffers all outputs to *STANDARD-OUTPUT* in BODY and flushes them to
*STANDARD-OUTPUT* after BODY has been done (without error). 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*))
  "NOTE: cannot read -2^62"
  (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))))))))

;;;
;;; Rolling hash (62-bit)
;;;

;; Reference:
;; https://www.mii.lt/olympiads_in_informatics/pdf/INFOL119.pdf
;; https://ei1333.github.io/luzhiled/snippets/string/rolling-hash.html

(defstruct (rhash (:constructor %make-rhash (cumul1 powers1 cumul2 powers2)))
  ;; lower 31-bit value
  (cumul1 nil :type (simple-array (unsigned-byte 31) (*)))
  (powers1 nil :type (simple-array (unsigned-byte 31) (*)))
  ;; upper 31-bit value
  (cumul2 nil :type (simple-array (unsigned-byte 31) (*)))
  (powers2 nil :type (simple-array (unsigned-byte 31) (*))))

(eval-when (:compile-toplevel :load-toplevel :execute)
  ;; This table consists of pairs of primes less than 2^31 and the random
  ;; primitive roots modulo them larger than 10^9. We randomly choose a pair and
  ;; adopt the prime as modulus and the primitive root as base.
  (declaim ((simple-array (unsigned-byte 31) (100)) *moduli-table* *base-table*))
  (defparameter *moduli-table*
    (make-array 100 :element-type '(unsigned-byte 31)
                    :initial-contents '(2147483647 2147483629 2147483587 2147483579 2147483563 2147483549 2147483543
 2147483497 2147483489 2147483477 2147483423 2147483399 2147483353 2147483323
 2147483269 2147483249 2147483237 2147483179 2147483171 2147483137 2147483123
 2147483077 2147483069 2147483059 2147483053 2147483033 2147483029 2147482951
 2147482949 2147482943 2147482937 2147482921 2147482877 2147482873 2147482867
 2147482859 2147482819 2147482817 2147482811 2147482801 2147482763 2147482739
 2147482697 2147482693 2147482681 2147482663 2147482661 2147482621 2147482591
 2147482583 2147482577 2147482507 2147482501 2147482481 2147482417 2147482409
 2147482367 2147482361 2147482349 2147482343 2147482327 2147482291 2147482273
 2147482237 2147482231 2147482223 2147482121 2147482093 2147482091 2147482081
 2147482063 2147482021 2147481997 2147481967 2147481949 2147481937 2147481907
 2147481901 2147481899 2147481893 2147481883 2147481863 2147481827 2147481811
 2147481797 2147481793 2147481673 2147481629 2147481571 2147481563 2147481529
 2147481509 2147481499 2147481491 2147481487 2147481373 2147481367 2147481359
 2147481353 2147481337)))
  (defparameter *base-table*
    (make-array 100 :element-type '(unsigned-byte 31)
                    :initial-contents '(1059428526 2090066834 1772913519 1695158082 1516083910 1622025757 1248368302
 1894391153 2094976878 1193495823 1783230399 1520742486 1748395380 1703688443
 2138630366 1942049269 2066548889 1890950855 1480056952 1792721876 1092797280
 1204851872 1035383130 1002272185 1319736653 1980774767 1748793187 1866963602
 1200445534 1732959733 1214706585 1957228822 1479411729 1323155655 1052714514
 1989821027 1163834549 1095622874 2087901566 1670886084 1191975321 2091468260
 1429690292 1116037844 1420457779 1937649612 1552519679 1328604092 2090326292
 1397132095 1316705322 1664351025 1391513321 1851038917 1556301575 1928956735
 1764506480 1449537491 2119470570 1793768237 1831208371 1723755364 1643456516
 1993819805 1419297891 1755252963 1775153034 1388979165 2144586633 1501222238
 1872274033 1143076711 1229125474 1483974015 1997206147 1593231852 1632083893
 1601537043 2012194627 1299923971 1566635240 1814404069 1619988648 2072686565
 2014361572 1213868607 1166967329 1009325840 1306167671 1915239658 1223190075
 1821151471 2037700892 1646950698 1517859810 1099233635 1004913731 1653443892
 1782112665 1018916580)))

  (defun %choose-moduli (&optional mod1 mod2 base1 base2)
    "Chooses two appropriate pairs of moduli and bases."
    (declare ((or null (unsigned-byte 31)) mod1 mod2 base1 base2))
    (let* ((rand1 (random (length *moduli-table*)))
           (rand2 (loop (let ((tmp (random (length *moduli-table*))))
                          (unless (= tmp rand1)
                            (return tmp))))))
      (if mod1
          (progn
            #+sbcl (assert (sb-int:positive-primep mod1))
            (setq base1 (or base1 (+ 1 (random (- mod1 1))))))
          (progn
            (setq mod1 (or mod1 (aref *moduli-table* rand1)))
            (if base1
                (assert (<= 1 base1 (- mod1 1)))
                (setq base1 (aref *base-table* rand1)))))
      (if mod2
          (progn
            #+sbcl (assert (sb-int:positive-primep mod2))
            (setq base2 (or base2 (+ 1 (random (- mod2 1))))))
          (progn
            (setq mod2 (or mod2 (aref *moduli-table* rand2)))
            (if base2
                (assert (<= 1 base2 (- mod2 1)))
                (setq base2 (aref *base-table* rand2))))))
    (values mod1 mod2 base1 base2))

  (unless (and (boundp '+rhash-mod1+)
               (boundp '+rhash-mod2+)
               (boundp '+rhash-base1+)
               (boundp '+rhash-base2+))
    (multiple-value-bind (mod1 mod2 base1 base2) (%choose-moduli)
      (defconstant +rhash-mod1+ mod1)
      (defconstant +rhash-mod2+ mod2)
      (defconstant +rhash-base1+ base1)
      (defconstant +rhash-base2+ base2))))

;; KLUDGE: Type derivation of MOD fails in some cases on SBCL. See
;; https://bugs.launchpad.net/sbcl/+bug/1843108
(declaim (inline %mod))
(defun %mod (number divisor)
  (nth-value 1 (floor number divisor)))

(declaim (inline make-rhash))
(defun make-rhash (vector &key (key #'char-code))
  "Returns the table of rolling-hash of VECTOR modulo +RHASH-MOD1+ and
+RHASH-MOD2+. KEY is applied to each element of VECTOR prior to computing the
hash value.

KEY := FUNCTION returning FIXNUM"
  (declare (optimize (speed 3))
           (vector vector)
           (function key))
  (let* ((size (length vector))
         (cumul1 (make-array (+ 1 size) :element-type '(unsigned-byte 31)))
         (powers1 (make-array (+ 1 size) :element-type '(unsigned-byte 31)))
         (cumul2 (make-array (+ 1 size) :element-type '(unsigned-byte 31)))
         (powers2 (make-array (+ 1 size) :element-type '(unsigned-byte 31))))
    (setf (aref powers1 0) 1
          (aref powers2 0) 1)
    (dotimes (i size)
      (setf (aref powers1 (+ i 1))
            (%mod (* (aref powers1 i) +rhash-base1+) +rhash-mod1+)
            (aref powers2 (+ i 1))
            (%mod (* (aref powers2 i) +rhash-base2+) +rhash-mod2+))
      (let ((sum1 (+ (%mod (* +rhash-base1+ (aref cumul1 i)) +rhash-mod1+)
                     (%mod (the fixnum (funcall key (aref vector i))) +rhash-mod1+)))
            (sum2 (+ (%mod (* +rhash-base2+ (aref cumul2 i)) +rhash-mod2+)
                     (%mod (the fixnum (funcall key (aref vector i))) +rhash-mod2+))))
        (setf (aref cumul1 (+ i 1)) (if (>= sum1 +rhash-mod1+)
                                        (- sum1 +rhash-mod1+)
                                        sum1)
              (aref cumul2 (+ i 1)) (if (>= sum2 +rhash-mod2+)
                                        (- sum2 +rhash-mod2+)
                                        sum2))))
    (%make-rhash cumul1 powers1 cumul2 powers2)))

(declaim (ftype (function * (values (unsigned-byte 62) &optional)) rhash-vector-hash)
         (inline rhash-vector-hash))
(defun rhash-vector-hash (vector &key (key #'char-code))
  "Returns the hash code of VECTOR w.r.t. the moduli and bases of RHASH."
  (declare (optimize (speed 3))
           (vector vector)
           (function key))
  (let* ((size (length vector))
         (lower 0)
         (upper 0))
    (declare ((unsigned-byte 31) lower upper))
    (dotimes (i size)
      (setf lower (%mod (+ (* +rhash-base1+ lower)
                          (%mod (the fixnum (funcall key (aref vector i))) +rhash-mod1+))
                       +rhash-mod1+))
      (setf upper (%mod (+ (* +rhash-base2+ upper)
                          (%mod (the fixnum (funcall key (aref vector i))) +rhash-mod2+))
                       +rhash-mod2+)))
    (dpb upper (byte 31 31) lower)))

(declaim (inline rhash-query)
         (ftype (function * (values (unsigned-byte 62) &optional)) rhash-query))
(defun rhash-query (rhash l r)
  "Returns the hash value of the interval [L, R)."
  (declare ((integer 0 #.most-positive-fixnum) l r))
  (assert (<= l r))
  (let ((cumul1 (rhash-cumul1 rhash))
        (powers1 (rhash-powers1 rhash))
        (cumul2 (rhash-cumul2 rhash))
        (powers2 (rhash-powers2 rhash)))
    (let ((lower (+ (aref cumul1 r)
                    (- +rhash-mod1+ (%mod (* (aref cumul1 l) (aref powers1 (- r l))) +rhash-mod1+))))
          (upper (+ (aref cumul2 r)
                    (- +rhash-mod2+ (%mod (* (aref cumul2 l) (aref powers2 (- r l))) +rhash-mod2+)))))
      (let ((lower (if (>= lower +rhash-mod1+) (- lower +rhash-mod1+) lower))
            (upper (if (>= upper +rhash-mod2+) (- upper +rhash-mod2+) upper)))
        (declare ((unsigned-byte 31) lower upper))
        (dpb upper (byte 31 31) lower)))))

(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 ()
  (declare #.OPT)
  (let* ((n (read))
         (as (make-array n :element-type 'uint31))
         (bs (make-array n :element-type 'uint31))
         (adeltas (make-array (* 2 n) :element-type 'uint31))
         (bdeltas (make-array n :element-type 'uint31)))
    (declare (uint31 n))
    (dotimes (i n)
      (setf (aref as i) (read-fixnum)))
    (dotimes (i n)
      (setf (aref bs i) (read-fixnum)))
    (dotimes (i (- n 1))
      (setf (aref adeltas i) (logxor (aref as i) (aref as (+ i 1)))
            (aref adeltas (+ i n)) (aref adeltas i))
      (setf (aref bdeltas i) (logxor (aref bs i) (aref bs (+ i 1)))))
    (setf (aref adeltas (- n 1))
          (logxor (aref as (- n 1)) (aref as 0))
          (aref adeltas (- (* 2 n) 1)) (aref adeltas (- n 1)))
    (setf (aref bdeltas (- n 1)) (logxor (aref bs (- n 1)) (aref bs 0)))
    (let ((ahash (make-rhash adeltas :key #'identity))
          (bhash (rhash-vector-hash bdeltas :key #'identity)))
      (with-buffered-stdout
        (dotimes (i n)
          (when (= (rhash-query ahash i (+ i n)) bhash)
            (format t "~D ~D~%" i (logxor (aref as i) (aref bs 0)))))))))

#-swank (main)

;;;
;;; Test and benchmark
;;;

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    ;; (run-program "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" '("get-clipboard") :output out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :output out :search t)))

#+swank (defparameter *this-pathname* (uiop:current-lisp-file-pathname))
#+swank (defparameter *dat-pathname* (uiop:merge-pathnames* "test.dat" *this-pathname*))

#+swank
(defun run (&optional thing (out *standard-output*))
  "THING := null | string | symbol | pathname

null: run #'MAIN using the text on clipboard as input.
string: run #'MAIN using the string as input.
symbol: alias of FIVEAM:RUN!.
pathname: run #'MAIN using the text file as input."
  (let ((*standard-output* out))
    (etypecase thing
      (null
       (with-input-from-string (*standard-input* (delete #\Return (get-clipbrd)))
         (main)))
      (string
       (with-input-from-string (*standard-input* (delete #\Return thing))
         (main)))
      (symbol (5am:run! thing))
      (pathname
       (with-open-file (*standard-input* thing)
         (main))))))

#+swank
(defun gen-dat ()
  (uiop:with-output-file (out *dat-pathname* :if-exists :supersede)
    (format out "")))

#+swank
(defun bench (&optional (out (make-broadcast-stream)))
  (time (run *dat-pathname* out)))

;; To run: (5am:run! :sample)
#+swank
(it.bese.fiveam:test :sample
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "3
0 2 1
1 2 3
"
    "1 3
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "5
0 0 0 0 0
2 2 2 2 2
"
    "0 2
1 2
2 2
3 2
4 2
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "6
0 1 3 7 6 4
1 5 4 6 2 3
"
    "2 2
5 5
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "2
1 2
0 0
"
    "
")))