Skip to content

Commit 5f6f584

Browse files
authored
Merge pull request #145 from Phluenam/add_1134
Add 1134
2 parents a669452 + c8a6326 commit 5f6f584

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

md/1134.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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

Comments
 (0)