# TKNP
*sau Tết*
## Mô hình chung
```cpp
while (l <= r) {
mid = (l+r) / 2
check(mid);
}
```
Cái khó của mỗi bài nằm ở hàm `check`
### Tài liệu
- https://vnoi.info/wiki/algo/basic/binary-search.md
- https://codeforces.com/edu/courses, đăng ký "Pilot course" và vào phần practice của 5 step.
## Tìm trong mảng:
+ tìm vị trí $j$ lớn nhất,
+ $a[j] \le v$ (cho trước $v$)
(maxle, minge)
## Mua bài
$f(x)$ = số tiền phải trả để mua $x$ bộ bài. Vậy phải tìm
+ $x$ lớn nhất
+ $f(x) \le C$
Làm tương tự như tìm trong mảng, nhưng không có sẵn mảng đó mà mỗi lần hỏi là phải tính lại $f$.
Ví dụ: `if (a[mid] > val)` chuyển thành `if (f(mid) > val)` (tự viết $f$ theo đề)
## Bảng cửu chương
### Kiến thức chung
tìm số thứ $k$ trong một mảng A có kích thước rất lớn
--> tạo hàm `cnt(x)` là số lượng số trong mảng A mà $\le x$
Giá trị thứ $k$ sẽ là:
+ $x$ nhỏ nhất
+ mà `cnt(x)` $\ge k$
### Hướng giải
Đếm xem có bao nhiêu cặp $i,j (1\le i,j\le n)$ mà $i \times j \le x$
Vậy chỉ cần chạy for $i$, lấy được giá trị lớn nhất có thể của $j = min(\lfloor\frac{x}{i}\rfloor, n)$
Thứ tự cần tìm = (Số lượng+1) / 2
## Kích thước mảng con lớn nhất
Bài toán vận dụng khá hay. Có hai hướng:
- TKNP đáp án: giả sử kích thước lớn nhất $\ge x$. Cứ coi như kích thước bằng đúng $x$, thử tính xem tổng của mọi mảng con độ dài $\le x$ có đúng là $<k$ thật không? (tuy nhiên việc tính này không đơn giản lắm [set, 2 con trỏ, prefix-sum, ...])
- Suy nghĩ đơn giản: Tại mỗi vị trí $i$, tìm vị trí $j$ xa nhất mà tổng đoạn $[i,j] < k$. Vậy đáp án là $\min(j-i+1)$ của các $i$.