|
| 1 | +ข้อนี้ให้ค่า $A,B,C,D,E,F,G,H$ และกำหนด $a_1=A, a_2=B,a_3=C,a_4=D$ และ $a_k = E a_{k-1} + F a_{k-2} + G a_{k-3} + H a_{k-4}$ |
| 2 | + |
| 3 | +จากนั้นให้ $Q\leq 200000$ คำถาม ในแต่ละคำถามให้หาค่า $a_N$ สำหรับ $N\leq 10^{18}$ |
| 4 | + |
| 5 | +### เคส $ N \leq 1000000$ |
| 6 | + |
| 7 | +ในเคสนี้สามารถคำนวณ $a_5, a_6, \dots, a_{1000000}$ ไว้ก่อนโดยใช้ recurrence ที่โจทย์กำหนดและเก็บมาตอบคำถาม $Q$ ข้อ |
| 8 | + |
| 9 | +การตอบคำถามจะใช้เวลาเพียง $\mathcal{O}(1)$ และการคำนวณแต่ละ $a_k = Fa_{k-1} + E a_{k-2} + Ga_{k-3} +H a_{k-4}$ ใข้ $\mathcal{O}(1)$ สำหรับแต่ละ $k$ เช่นกันซึ่งต้องทำ 1000000 ครั้ง จึงเร็วเพียงพอสำหรับเคสนี้ |
| 10 | + |
| 11 | +### เคส $Q \leq 2000$ |
| 12 | + |
| 13 | +สำหรับเคสนี้สามารถสังเกต |
| 14 | + |
| 15 | +$\begin{bmatrix}\ a_k \\\ a_{k-1} \\\ a_{k-2} \\\ a_{k-3} \end{bmatrix}= \begin{bmatrix} E & F & G & H \\ 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix}\ a_{k-1} \\\ a_{k-2} \\\ a_{k-3} \\\ a_{k-4} \end{bmatrix}$ |
| 16 | + |
| 17 | +ให้ $A = \begin{bmatrix} E & F & G & H \\ 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} $ จะได้ว่า $\begin{bmatrix} \ a_k \\\ a_{k-1} \\\ a_{k-2} \\\ a_{k-3} \end{bmatrix}= A \begin{bmatrix}\ a_{k-1} \\\ a_{k-2} \\\ a_{k-3} \\\ a_{k-4} \end{bmatrix}$ |
| 18 | + |
| 19 | +สังเกตว่า |
| 20 | + |
| 21 | + $\begin{bmatrix} \ a_N \\\ a_{N-1} \\\ a_{N-2} \\\ a_{N-3} \end{bmatrix}= A\begin{bmatrix}\ a_{N-1} \\\ a_{N-2} \\\ a_{N-3} \\\ a_{N-4} \end{bmatrix} = A^2 \begin{bmatrix}\ a_{N-2} \\\ a_{N-3} \\\ a_{N-4} \\\ a_{N-5} \end{bmatrix} = \dots = A^{N-4} \begin{bmatrix} \ a_{4}\\\ a_{3}\\\ a_{2}\\\ a_{1}\end{bmatrix} = A^{N-4} \begin{bmatrix} \ D \\\ C\\\ B \\\ A \end{bmatrix}$ |
| 22 | + |
| 23 | +หากใช้ Matrix Exponentiation จะทำให้คำนวณ $A^{N-4}$ ได้ในเวลา $\mathcal{O}(M \log N)$ เมื่อ $M$ คือเวลาที่ใช้ในการทำ Matrix Multiplication หนึ่งรอบ หากใช้วิธีปกติจะเป็น $\mathcal{O}(r^3)$ สำหรับ Matrix ขนาด $r\times r$ ($r=4$) |
| 24 | + |
| 25 | +เมื่อทำสำหรับทุกคำถามจะเป็น $\mathcal{O}(Q r^3 \log N)$ ซึ่งเร็วพอสำหรับ $Q \leq 2000$ แต่อาจช้าไปสำหรับเคสที่ใหญ่กว่านั้น |
| 26 | + |
| 27 | +#### Matrix Multiplication |
| 28 | + |
| 29 | +วิธี Matrix Exponentiation เริ่มจากการสังเกตว่าหาก $N = (b_{\lfloor \log N \rfloor } b_{\lfloor \log N \rfloor -1} \dots b_0)_2$ นั่นคือ $N$ มี Binary Representation (การแทนแบบฐานสอง) เป็น $b_{\lfloor \log N \rfloor } b_{\lfloor \log N \rfloor -1} \dots b_0$ จะได้ว่า $N = 2^{\lfloor \log N \rfloor}{b_{\lfloor \log N \rfloor }} + 2^{\lfloor \log N \rfloor -1}{b_{\lfloor \log N \rfloor -1}} + \dots + 2^0{b_0}$ |
| 30 | + |
| 31 | +ซึ่งทำให้ได้ว่า $A^N = A^{2^{\lfloor \log N \rfloor}{b_{\lfloor \log N \rfloor }} }A^{2^{\lfloor \log N \rfloor -1}{b_{\lfloor \log N \rfloor -1}}} \dots A^{2^0{b_0}} $ |
| 32 | + |
| 33 | +เช่นถ้า $N= 13 = 1101_2 $ ก็จะได้ $A^{13} = A^{2^3 \times 1} A^{2^2 \times 1} A^{2^1 \times 0} A^{2^0 \times 1} = A^8 A^4 A^1$ |
| 34 | + |
| 35 | +สังเกตว่า $A^{2^i}$ คำนวณได้จาก $A^{2^{i}} = A^{2^{i-1}} A^{2^{i-1}} $ ดังนั้นการคำนวณ $A^{2^{i}}$ สำหรัรบทุก $i$ ตั้งแต่ $1$ ถึง $\lfloor \log N \rfloor$ จะใช้เวลา $\mathcal{O}(r^3 \log N ) $ ดังนั้นการคำนวณ $A^N$ เพียงต้องเลือกเฉพาะค่า $i$ ที่ $b_i = 1$ ใน Binary Represenation ของ $N$ มาคูณกัน ซึ่งใช้เวลา $\mathcal{O}(r^3 \log N)$ เช่นกัน |
| 36 | + |
| 37 | +##### ตัวอย่างการเขียน Matrix Exponentiation |
| 38 | + |
| 39 | +เริ่มด้วย Function MUL(X,Y,R) สำหรับการทำ Matrix Multiplication เพื่อแก้ค่า $R$ ให้เป็น $X Y$ |
| 40 | + |
| 41 | +```cpp |
| 42 | +void mul(int X[4][4], int Y[4][4], int R[4][4]) { |
| 43 | + int M[4][4] = {}; |
| 44 | + for (int r = 0; r < 4; r++) |
| 45 | + for (int c = 0; c < 4; c++) |
| 46 | + for (int k = 0; k < 4; k++) |
| 47 | + M[r][c] += X[r][k] * Y[k][c]; |
| 48 | + |
| 49 | + for (int r = 0; r < 4; r++) |
| 50 | + for (int c = 0; c < 4; c++) |
| 51 | + R[r][c] = M[r][c]; |
| 52 | +} |
| 53 | +``` |
| 54 | +
|
| 55 | +ในการคำนวณ $A^N$ เราจะไล่ตั้งแต่ $i=0$ ถึง $i=\lfloor \log N \rfloor $ และหา $A^{2^i}$ โดย สำหรับ $i=0$ จะเอาค่าจาก $A$ มาโดยตรง ส่วนสำหรับ $i \geq 1$ จำใช้ $A^{2^i} = A^{2^{i-1}} A^{2^{i-1}}$ ดังที่อธิบายไว้ ส่วนการคำนวณ ผลลัพท์จะเริ่มจากตั้ง $C = I$ (เมทริกซ์เอกลักษณ์) และแก้เป็น $C = A^{2^i}$ เมื่อเลขตัวที่ $b_i = 1$ ซึ่งสามารถตรวจสอบโดยใช้ bit operation เพราะ $b_i = 1$ เมื่อ $(1LL<<i) \& N \neq 0$ ($(1LL<<i) $ คือการ shift 1 มาด้านซ้าย $i$ รอบ ถ้า $\&$ กับ $N$ และได้ค่าที่ไม่ใช่ 0 แสดงว่า bit นี้ใน $N$ เป็น 1) |
| 56 | +
|
| 57 | +```cpp |
| 58 | +void exp(int A[4][4], long long N, int result[4][4]) { |
| 59 | + int A_pow_2[65][4][4]; |
| 60 | + int C[4][4] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; |
| 61 | + for (int b = 0; (1LL << b) <= N; b++) { |
| 62 | + if (b == 0) { |
| 63 | + for (int r = 0; r < 4; r++) |
| 64 | + for (int c = 0; c < 4; c++) |
| 65 | + A_pow_2[b][r][c] = A[r][c]; |
| 66 | + } else { |
| 67 | + mul(A_pow_2[b - 1], A_pow_2[b - 1], A_pow_2[b]); |
| 68 | + } |
| 69 | +
|
| 70 | + if ((1LL << b) & N) |
| 71 | + mul(A_pow_2[b], C, C); |
| 72 | + } |
| 73 | +
|
| 74 | + for (int r = 0; r < 4; r++) |
| 75 | + for (int c = 0; c < 4; c++) |
| 76 | + result[r][c] = C[r][c]; |
| 77 | + return; |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +### เคส $Q \leq 200000$ |
| 82 | + |
| 83 | +สำหรับเคสสุดท้ายสังเกตว่าในแต่ละ Test Case ค่า $A,B,C,D,E,F,G,H$ จะไม่เปลี่ยน ดังนั้นเราสามารถคำนวณ $A^0, A^1, \dots, A^{\lfloor \log 10^{18} \rfloor}$ ไว้ล่วงหน้า โดยใช้เวลา $\mathcal{O}(r^3 \log N)$ |
| 84 | + |
| 85 | +ตอนคำนวณคำตอบแต่ละ $N$ เมื่อให้ $N -4 = (b_{\lfloor \log N \rfloor } b_{\lfloor \log N \rfloor -1} \dots b_0)_2$ |
| 86 | +เราสามารถคำนวณเป็น $(A^{2^{\lfloor \log N \rfloor}{b_{\lfloor \log N \rfloor }} }(A^{2^{\lfloor \log N \rfloor -1}{b_{\lfloor \log N \rfloor -1}}} (\dots (A^{2^0{b_0}} \begin{bmatrix} \ D \\\ C\\\ B \\\ A \end{bmatrix}) \dots ) ) )$ นั่นคือในการคูณจะคูณด้านหลังสุดก่อนเพื่อให้เป็นการคูณ Matrix ขนาด $r \times r$ กับ Vector ขนาด $r \times 1$ ซึ่งทำให้เวลาในการคูณเหลือ $\mathcal{O}(r^2)$ แทนที่จะเป็น $\mathcal{O}(r^3)$ ในแต่ละรอบการคูณ |
| 87 | + |
| 88 | +การตอบคำถามสำหรับ $N$ ค่าหนึ่งจึงใช้เวลา $\mathcal{O}(r^2 \log N)$ |
| 89 | + |
| 90 | +ดังนั้นเวลาทั้งหมดที่ใช้คือ $\mathcal{O}(r^3 \log N) + \mathcal{O}(Qr^2 \log N)$ ซึ่งเร็วเพียงพอสำหรับข้อนี้ |
| 91 | + |
0 commit comments