# Contest Hà Nội - những bài khó ## Phương trình: ### Ăn 87,5% số test Cày trâu, nhớ kiểm tra: - chia hết - dương ### Full Giải [phương trình diophantine](https://cp-algorithms.com/algebra/linear-diophantine-equation.html) bằng Euclid mở rộng #### Một cách khác $2x+4y=20$ có các cặp nghiệm $(x, y)$ là: $(2, 4); (4, 3); (6, 2); (8, 1)$ ta thấy, với mỗi cặp nghiệm, x tăng đều 2 đơn vị và y giảm đều 1 đơn vị Để tổng quát, ta đặt $d = \gcd(a, b), a' = \dfrac{b}{d}, b' = \dfrac{a}{d}$. Khi đó, nếu ta tìm được cặp nghiệm $(x, y)$ sao cho $ax + by = c$, thì cặp nghiệm $(x \pm a', y \mp b')$ cũng thỏa mãn. Nôm na là một bên tăng thêm $\dfrac{ab}{d}$, một bên giảm bớt để bù lại. Vì vậy, ta tìm nghiệm $(x, y)$ với $x$ nhỏ nhất thỏa mãn phương trình trên, sau đó đếm xem có bao nhiêu cặp nghiệm nguyên dương $(x + ka', y - kb')$ thỏa mãn $(k \in \mathbb{N} = \{0, 1, 2, \dots\})$. Đáp án có thể tính bằng cách đặt $k = \min(\dfrac{c - x}{a'}, \dfrac{y}{b'})$, đáp án là $k+1$. Để tìm nghiệm $x$ nhỏ nhất, ta chỉ cần duyệt trâu. Lý do là: - nếu vô nghiệm, đó là vì $c$ không chia hết cho $\gcd(a, b)$ (tính chất của phương trình Diophantine). ta chỉ cần thêm điều kiện này là xong - ngược lại, nếu đặt $a > b$ thì tìm $x$ rất nhanh. vì sao nhanh? - $a, b$ lớn thì duyệt ít - $a, b$ nhỏ thì nghiệm $x$ nhỏ. ## Tìm xâu ### Tóm tắt đề Lấy một xâu $x$ bất kì, "quay vòng tròn" nó ra được các xâu (VD `abab` quay vòng ra được `abab`, `baba`, `abab`, `baba`). Nhưng chỉ quan tâm những xâu khác nhau (tức là `abab` và `baba`). Sắp xếp tăng dần mấy xâu ni, hỏi xâu thứ $k$ là xâu nào? ### Cách giải Từ việc hiểu rõ đề, cách làm cũng rõ ràng. Vậy làm sao để lấy ra được các xâu **khác nhau**? - Sau khi sắp xếp, những xâu giống nhau phải nằm liên tiếp - `set`, `map` ## Di chuyển cây Bước 1: đọc hiểu đề ## Tiếp cận Tạo mảng đánh dấu `m[i][j] = true/false` tương ứng với việc ô $(i,j)$ có thuộc một dãy dọc hoặc một dãy ngang nào không? Sau đó thì xét từng dòng riêng, và two-pointer. (cột làm tương tự) ## Cụ thể - Có thể xử lý riêng dòng và cột - Xét riêng dòng $r$, bài toán đưa về: cho một mảng $a$, tìm độ dài các đoạn con liên tiếp. - Bài toán con này giải được trong $O(n)$ bằng khá nhiều cách: + two-pointer + Đặt `f[i] = ` số lượng số liên tiếp, bằng với $a[i]$ (nằm ở bên trái nếu duyệt $i$ từ trái sang phải) ## Biến đổi xâu kí tự Hình dung: bảng HCN có kích thước $n$ hàng, $d$ cột, mỗi ô chứa một kí tự. Giả sử chọn xâu thứ $i$ làm "xâu gốc". Giữ lại một vài kí tự của xâu này, còn những vị trí khác lấy từ các xâu $j \neq i$ (bằng cách tráo). Để dùng ít thao tác nhất thì: những vị trí nào trong xâu thứ $i$ **đã giống** xâu mẫu $s$ rồi thì không cần đổi. Cần kiểm tra tại những vị trí (cột) còn lại, trên các xâu khác $i$ có chứa kí tự **cần tìm** không? ## Xây dựng đường băng Đặt $a[i][j] = |h - a[i][j]|$ (chênh lệch độ cao) Kích thước đường băng bằng đúng $d,r$. Lưu ý có thể xoay theo hai chiều ngang/dọc, ($d$ dòng $r$ cột hoặc $r$ dòng $d$ cột). Tổng tiền tố hai chiều. ## Trồng cây Bài khó. Xem ở đây: [Trồng cây (HSG9-2014, Hà Nội)](/ZHP9mjTRTWKZ0Dmk2nh8OA)